2

I am fetching price from a site in format: 10.990,00 which does not make sense as such. What is needed to make it as 10,990.00. I tried following but it's replacing all.

price = "10.990,00"
price = price.replace(',','.',1)
price = price.replace('.',',',1)

What am I doing wrong?

Daniel
  • 5,095
  • 5
  • 35
  • 48
Volatil3
  • 14,253
  • 38
  • 134
  • 263
  • 7
    The existing answers do a good job of answering your question, but taking a step back, what are you trying to accomplish? If you're trying to "fetch prices from a site and display them in your local currency, regardless of the source currency," you might benefit from converting the price to a number, then using your locale to display the price properly: http://stackoverflow.com/questions/8421922/how-do-i-convert-a-currency-string-to-a-floating-point-number-in-python and http://stackoverflow.com/questions/3606517/python-how-to-format-currency-string – Peach Mar 13 '15 at 15:29
  • Of course, my suggestion above doesn't account for currency conversion... but that's a whole other issue... – Peach Mar 13 '15 at 15:30
  • The site I am scraping mistakenly swapped commas and dots. – Volatil3 Mar 13 '15 at 15:33
  • 4
    @Volatil3: while it could be a mistake, it's worth remembering that not everyone on Earth uses the same comma/period conventions for formatting numbers. – DSM Mar 13 '15 at 15:40

5 Answers5

11

You are replacing the first dot with a comma, after first replacing the first comma with a dot. The dot the first str.replace() inserted is not exempt from being replaced by the second str.replace() call.

Use the str.translate() method instead:

try:
    from string import maketrans   # Python 2
except ImportError:
    maketrans = str.maketrans      # Python 3

price = price.translate(maketrans(',.', '.,'))

This'll swap commas for dots and vice versa as it traverses the string, and won't make double replacements, and is very fast to boot.

I made the code compatible with both Python 2 and 3, where string.maketrans() was replaced by a the static str.maketrans() function.

The exception here is Python 2 unicode; it works the same as str.translate() in Python 3, but there is no maketrans factory to create the mapping for you. You can use a dictionary for that:

unicode_price = unicode_price.translate({u'.': u',', u',': u'.'})

Demo:

>>> try:
...     from string import maketrans   # Python 2
... except ImportError:
...     maketrans = str.maketrans      # Python 3
... 
>>> price = "10.990,00"
>>> price.translate(maketrans(',.', '.,'))
'10,990.00'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • It's interesting I am on Py27 and it says `Uresolved Reference` for `maketrans` – Volatil3 Mar 13 '15 at 15:29
  • @Volatil3: that sounds like your IDE is telling you that; is it PyCharm? You can just use the first line without the `try..except` and PyCharm will not complain anymore, or you could just ignore that warning; the IDE sees the `maketrans = str.maketrans` line and doesn't know it will never be executed on Python 2. – Martijn Pieters Mar 13 '15 at 15:30
  • Yes it's PyCharm :-) let me run then – Volatil3 Mar 13 '15 at 15:31
  • For python2, I'd add a note that this won't work for unicode strings (e.g. they're getting `price` from some json). – georg Mar 13 '15 at 15:35
  • @georg: at which point you'd have to use your own dictionary: `{u'.': u',', u',': u'.'}`. – Martijn Pieters Mar 13 '15 at 15:35
  • @MartijnPieters I am getting: ` type object 'str' has no attribute 'mktrans'` – Volatil3 Mar 13 '15 at 15:42
  • @MartijnPieters is it `maketrans`? – Volatil3 Mar 13 '15 at 15:43
  • @Volatil3: it is maketrans, I mistyped the name before. – Martijn Pieters Mar 13 '15 at 15:44
  • So, you ended up with `try... import-maketrans-thing.... if unicode translate-with-dict else translate-with-maketrans ` - 8 lines in total. A bit too much for the OP's problem, isn't it? ;) – georg Mar 13 '15 at 15:47
  • @georg: only if you are going to re-use the code in this answer for something that must work with both `str` and `unicode` in Python 2, and `str` in Python 3 all in one codebase. But I now at least covered all the bases. – Martijn Pieters Mar 13 '15 at 15:48
3

The reason your code doesn't work is because you convert 10.990,00 to 10.990.00 and then you are replacing all dots with comma.

Instead you can convert , to a symbol then convert . to , and the symbol to . :

price = "10.990,00"
price = price.replace(',','COMMA')
price = price.replace('.',',')

price = price.replace('COMMA','.')

print(price)

Or as suggested by georg

price = price.replace(',','COMMA').replace('.',',').replace('COMMA','.')

Note that i removed the optional argument in replace(), since numbers like 1.200.000,30 would not convert as expected.

user
  • 5,370
  • 8
  • 47
  • 75
  • 2
    You actually don't need the "COMMA" thing here, just `price.replace('.','@').replace(',','.').replace('@',',')` – georg Mar 13 '15 at 15:30
  • 1
    It would be a big trouble if OP had to exchange 3 characters, 4 characters and so on :D – Heisenberg Mar 13 '15 at 15:56
  • @Heisenberg I agree, but since he only mentions `,` and `.` this solution would be ok. Creating an answer based on further assumptions might make it unnecessarily complex. – user Mar 13 '15 at 16:02
3

@Martijn has given the best answer. you can also iterate over the price and replace.

swap = {'.':',',',':'.'}
def switchDotsAndCommas(text):
    text = ''.join(swap.get(k, k) for k in text)
    print text

switchDotsAndCommas('10.990,00')
Heisenberg
  • 1,500
  • 3
  • 18
  • 35
  • 2
    This is essentially what `str.translate()` *does*. But way, way faster. – Martijn Pieters Mar 13 '15 at 15:37
  • @MartijnPieters Is it faster due to some other algo being used or something else? – Volatil3 Mar 13 '15 at 15:39
  • @MartijnPieters: yeah, but this is more generalizable, and uses a pattern which comes in handy in many other contexts as well. It's worth knowing about. – DSM Mar 13 '15 at 15:41
  • @DSM - it is as same as `list compression` is much faster than creating a list by iterating over other list as LC is entirely done in `C`. (I guess). – Heisenberg Mar 13 '15 at 15:55
0

May be this is a long answer but it is simple to execute and doesn't use any built in function:

l=input("enter the input:")
m=[]
for i in l:
 if(i=='.'):
  m.append(',')
 elif(i==','):
  m.append('.')
 else:
  m.append(i)
print(''.join(m))
dushyant
  • 349
  • 3
  • 7
-1
price = "10.990,00"
price = price.replace(',','.')
price1=price[0:3].replace('.',',')
print(price1+price[3:9])
sud
  • 1