Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #83556 > unrolled thread
| Started by | Store Makhzan <store0a@gmail.com> |
|---|---|
| First post | 2015-01-11 11:31 -0800 |
| Last post | 2015-01-12 12:13 +1100 |
| Articles | 19 — 9 participants |
Back to article view | Back to comp.lang.python
extracting numbers with decimal places from a string Store Makhzan <store0a@gmail.com> - 2015-01-11 11:31 -0800
Re: extracting numbers with decimal places from a string Joel Goldstick <joel.goldstick@gmail.com> - 2015-01-11 15:06 -0500
Re: extracting numbers with decimal places from a string Store Makhzan <store0a@gmail.com> - 2015-01-11 12:26 -0800
Re: extracting numbers with decimal places from a string Joel Goldstick <joel.goldstick@gmail.com> - 2015-01-11 16:42 -0500
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-11 23:20 +0100
Re: extracting numbers with decimal places from a string Joel Goldstick <joel.goldstick@gmail.com> - 2015-01-11 17:54 -0500
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 00:12 +0100
Re: extracting numbers with decimal places from a string Joel Goldstick <joel.goldstick@gmail.com> - 2015-01-11 18:35 -0500
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 00:46 +0100
Re: extracting numbers with decimal places from a string Peter Otten <__peter__@web.de> - 2015-01-12 01:09 +0100
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 01:45 +0100
Re: extracting numbers with decimal places from a string Chris Angelico <rosuav@gmail.com> - 2015-01-12 11:17 +1100
Re: extracting numbers with decimal places from a string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-12 11:45 +1100
Re: extracting numbers with decimal places from a string Grant Edwards <invalid@invalid.invalid> - 2015-01-11 23:06 +0000
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 00:07 +0100
Re: extracting numbers with decimal places from a string Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-12 00:04 +0000
Re: extracting numbers with decimal places from a string Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-01-12 02:00 +0100
Re: extracting numbers with decimal places from a string MRAB <python@mrabarnett.plus.com> - 2015-01-12 00:59 +0000
Re: extracting numbers with decimal places from a string Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-12 12:13 +1100
| From | Store Makhzan <store0a@gmail.com> |
|---|---|
| Date | 2015-01-11 11:31 -0800 |
| Subject | extracting numbers with decimal places from a string |
| Message-ID | <7240a574-dfd7-46c3-80eb-0657b41894bb@googlegroups.com> |
I have this script which can calculate the total of numbers given in a string ---- script ----- total = 0 for c in '0123456789': total += int(c) print total ---- script ----- How should I modify this script to find the total of if the numbers given in the string form have decimal places? That is, how do I need to modify this line: ----- script ----- for c in '1.32, 5.32, 4.4, 3.78': ----- script ----- to find the total of these given numbers.
[toc] | [next] | [standalone]
| From | Joel Goldstick <joel.goldstick@gmail.com> |
|---|---|
| Date | 2015-01-11 15:06 -0500 |
| Message-ID | <mailman.17591.1421006803.18130.python-list@python.org> |
| In reply to | #83556 |
On Sun, Jan 11, 2015 at 2:31 PM, Store Makhzan <store0a@gmail.com> wrote: > I have this script which can calculate the total of numbers given in a string > ---- script ----- > total = 0 > for c in '0123456789': > total += int(c) > print total > ---- script ----- > > How should I modify this script to find the total of if the numbers given in the string form have decimal places? That is, how do I need to modify this line: > ----- script ----- > for c in '1.32, 5.32, 4.4, 3.78': > ----- script ----- > to find the total of these given numbers. > -- > https://mail.python.org/mailman/listinfo/python-list split the string on ',' to get a list of strings. loop thru list using float(s), add float values -- Joel Goldstick http://joelgoldstick.com
[toc] | [prev] | [next] | [standalone]
| From | Store Makhzan <store0a@gmail.com> |
|---|---|
| Date | 2015-01-11 12:26 -0800 |
| Message-ID | <3bfeea22-cded-4363-92fa-6f1b33ddae16@googlegroups.com> |
| In reply to | #83559 |
On Sunday, January 11, 2015 at 2:06:54 PM UTC-6, Joel Goldstick wrote:
> On Sun, Jan 11, 2015 at 2:31 PM, Store Makhzan wrote:
> > I have this script which can calculate the total of numbers given in a string
> > ---- script -----
> > total = 0
> > for c in '0123456789':
> > total += int(c)
> > print total
> > ---- script -----
> >
> > How should I modify this script to find the total of if the numbers given in the string form have decimal places? That is, how do I need to modify this line:
> > ----- script -----
> > for c in '1.32, 5.32, 4.4, 3.78':
> > ----- script -----
> > to find the total of these given numbers.
> > --
> > https://mail.python.org/mailman/listinfo/python-list
>
> split the string on ',' to get a list of strings. loop thru list
> using float(s), add float values
>
>
> --
> Joel Goldstick
> http://joelgoldstick.com
Thank you
Here is what I did:
----- script -----
#Check if a perfect cube
total = 0
for c in ('1.23', '2.4', '3.123'):
print float(c)
total += float(c)
print total
----- script -----
Which gave me the result I wanted.
Since I am new to Python, I used () as a guess, and it worked.
[toc] | [prev] | [next] | [standalone]
| From | Joel Goldstick <joel.goldstick@gmail.com> |
|---|---|
| Date | 2015-01-11 16:42 -0500 |
| Message-ID | <mailman.17595.1421012580.18130.python-list@python.org> |
| In reply to | #83562 |
On Sun, Jan 11, 2015 at 3:26 PM, Store Makhzan <store0a@gmail.com> wrote:
> On Sunday, January 11, 2015 at 2:06:54 PM UTC-6, Joel Goldstick wrote:
>> On Sun, Jan 11, 2015 at 2:31 PM, Store Makhzan wrote:
>> > I have this script which can calculate the total of numbers given in a string
>> > ---- script -----
>> > total = 0
>> > for c in '0123456789':
>> > total += int(c)
>> > print total
>> > ---- script -----
>> >
>> > How should I modify this script to find the total of if the numbers given in the string form have decimal places? That is, how do I need to modify this line:
>> > ----- script -----
>> > for c in '1.32, 5.32, 4.4, 3.78':
>> > ----- script -----
>> > to find the total of these given numbers.
>> > --
>> > https://mail.python.org/mailman/listinfo/python-list
>>
>> split the string on ',' to get a list of strings. loop thru list
>> using float(s), add float values
>>
>>
>> --
>> Joel Goldstick
>> http://joelgoldstick.com
>
> Thank you
> Here is what I did:
>
> ----- script -----
> #Check if a perfect cube
> total = 0
> for c in ('1.23', '2.4', '3.123'):
> print float(c)
> total += float(c)
> print total
> ----- script -----
>
> Which gave me the result I wanted.
> Since I am new to Python, I used () as a guess, and it worked.
That's fine, but its different than your original question. In your
original question you had a string of floats separated by commas. To
solve that problem you need to first split the string on the commas:
my_list = "1.23, 2.4, 3.123".split(",")
that will give you ['1.23', '2.4', '3.123']
>From there do what you did starting with your for loop
> --
> https://mail.python.org/mailman/listinfo/python-list
--
Joel Goldstick
http://joelgoldstick.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-11 23:20 +0100 |
| Message-ID | <8077448.xvuXrbCisO@PointedEars.de> |
| In reply to | #83566 |
Joel Goldstick wrote:
> my_list = "1.23, 2.4, 3.123".split(",")
>
> that will give you ['1.23', '2.4', '3.123']
No, it gives
| $ python
| Python 2.7.9 (default, Dec 11 2014, 08:58:12)
| [GCC 4.9.2] on linux2
| Type "help", "copyright", "credits" or "license" for more information.
| >>> my_list = "1.23, 2.4, 3.123".split(",")
| >>> my_list
| ['1.23', ' 2.4', ' 3.123']
| >>>
| $ python3
| Python 3.4.2 (default, Dec 27 2014, 13:16:08)
| [GCC 4.9.2] on linux
| Type "help", "copyright", "credits" or "license" for more information.
| >>> my_list = "1.23, 2.4, 3.123".split(",")
| >>> my_list
| ['1.23', ' 2.4', ' 3.123']
| >>>
In order to get the result you described, one needs at least
| >>> '1.23, 2.4, 3.123'.split(', ')
| ['1.23', '2.4', '3.123']
This is safer:
| >>> from re import split
| >>> split(r'\s*,\s*', '1.23, 2.4, 3.123')
| ['1.23', '2.4', '3.123']
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Joel Goldstick <joel.goldstick@gmail.com> |
|---|---|
| Date | 2015-01-11 17:54 -0500 |
| Message-ID | <mailman.17599.1421016900.18130.python-list@python.org> |
| In reply to | #83568 |
On Sun, Jan 11, 2015 at 5:20 PM, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
> Joel Goldstick wrote:
>
>> my_list = "1.23, 2.4, 3.123".split(",")
>>
>> that will give you ['1.23', '2.4', '3.123']
>
> No, it gives
>
> | $ python
> | Python 2.7.9 (default, Dec 11 2014, 08:58:12)
> | [GCC 4.9.2] on linux2
> | Type "help", "copyright", "credits" or "license" for more information.
> | >>> my_list = "1.23, 2.4, 3.123".split(",")
> | >>> my_list
> | ['1.23', ' 2.4', ' 3.123']
> | >>>
>
> | $ python3
> | Python 3.4.2 (default, Dec 27 2014, 13:16:08)
> | [GCC 4.9.2] on linux
> | Type "help", "copyright", "credits" or "license" for more information.
> | >>> my_list = "1.23, 2.4, 3.123".split(",")
> | >>> my_list
> | ['1.23', ' 2.4', ' 3.123']
> | >>>
>
> In order to get the result you described, one needs at least
>
> | >>> '1.23, 2.4, 3.123'.split(', ')
> | ['1.23', '2.4', '3.123']
>
> This is safer:
>
> | >>> from re import split
> | >>> split(r'\s*,\s*', '1.23, 2.4, 3.123')
> | ['1.23', '2.4', '3.123']
>
I'm not sure what you are trying to point out as your examples confirm
my code. Am I missing something.
As for feeding a beginner regex solutions, I'm on the side that this
is a terrible idea. Regex is not something a beginner should worry
about!
> --
> PointedEars
>
> Twitter: @PointedEars2
> Please do not cc me. / Bitte keine Kopien per E-Mail.
> --
> https://mail.python.org/mailman/listinfo/python-list
--
Joel Goldstick
http://joelgoldstick.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-12 00:12 +0100 |
| Message-ID | <2182977.fJl0o3iPdP@PointedEars.de> |
| In reply to | #83572 |
Joel Goldstick wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Joel Goldstick wrote:
>>> my_list = "1.23, 2.4, 3.123".split(",")
>>>
>>> that will give you ['1.23', '2.4', '3.123']
>>
>> No, it gives
>>
>> […]
>> | >>> my_list = "1.23, 2.4, 3.123".split(",")
>> | >>> my_list
>> | ['1.23', ' 2.4', ' 3.123']
^ ^
>> | >>>
>>
>> In order to get the result you described, one needs at least
>>
>> | >>> '1.23, 2.4, 3.123'.split(', ')
>> | ['1.23', '2.4', '3.123']
>>
>> […]
>
> I'm not sure what you are trying to point out as your examples confirm
> my code.
No, they don't.
> Am I missing something.
^
(Is that a question.)
You are missing a leading space character because in the string the comma
was followed by one.
> As for feeding a beginner regex solutions, I'm on the side that this
> is a terrible idea. Regex is not something a beginner should worry
> about!
NAK.
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Joel Goldstick <joel.goldstick@gmail.com> |
|---|---|
| Date | 2015-01-11 18:35 -0500 |
| Message-ID | <mailman.17600.1421019325.18130.python-list@python.org> |
| In reply to | #83575 |
On Sun, Jan 11, 2015 at 6:12 PM, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
> Joel Goldstick wrote:
>
>> Thomas 'PointedEars' Lahn wrote:
>>> Joel Goldstick wrote:
>>>> my_list = "1.23, 2.4, 3.123".split(",")
>>>>
>>>> that will give you ['1.23', '2.4', '3.123']
>>>
>>> No, it gives
>>>
>>> […]
>>> | >>> my_list = "1.23, 2.4, 3.123".split(",")
>>> | >>> my_list
>>> | ['1.23', ' 2.4', ' 3.123']
> ^ ^
>>> | >>>
>>>
>>> In order to get the result you described, one needs at least
>>>
>>> | >>> '1.23, 2.4, 3.123'.split(', ')
>>> | ['1.23', '2.4', '3.123']
>>>
>>> […]
>>
>> I'm not sure what you are trying to point out as your examples confirm
>> my code.
>
> No, they don't.
>
>> Am I missing something.
> ^
> (Is that a question.)
>
> You are missing a leading space character because in the string the comma
> was followed by one.
I see that now. Performing float on each element of the list will
take care of that, or I guess .strip() on each first.
>
>> As for feeding a beginner regex solutions, I'm on the side that this
>> is a terrible idea. Regex is not something a beginner should worry
>> about!
>
> NAK.
>
> --
> PointedEars
>
> Twitter: @PointedEars2
> Please do not cc me. / Bitte keine Kopien per E-Mail.
> --
> https://mail.python.org/mailman/listinfo/python-list
--
Joel Goldstick
http://joelgoldstick.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-12 00:46 +0100 |
| Message-ID | <1786463.stBbe1naGD@PointedEars.de> |
| In reply to | #83576 |
Joel Goldstick wrote:
> On Sun, Jan 11, 2015 at 6:12 PM, Thomas 'PointedEars' Lahn
> <PointedEars@web.de> wrote:
>> Joel Goldstick wrote:
>>> Am I missing something.
>> ^
>> […]
>> You are missing a leading space character because in the string the comma
>> was followed by one.
>
> I see that now. Performing float on each element of the list will
> take care of that, or I guess .strip() on each first.
As I showed, .strip() is unnecessary. But float() is always necessary for
computing the sum and suffices indeed together with s.split() if s is just a
comma-separated list of numeric strings with optional whitespace leading and
trailing the comma:
print(sum(map(lambda x: float(x), s.split(',')))
Please trim your quotes to the relevant minimum.
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-01-12 01:09 +0100 |
| Message-ID | <mailman.17603.1421021375.18130.python-list@python.org> |
| In reply to | #83577 |
Thomas 'PointedEars' Lahn wrote:
> Joel Goldstick wrote:
>
>> On Sun, Jan 11, 2015 at 6:12 PM, Thomas 'PointedEars' Lahn
>> <PointedEars@web.de> wrote:
>>> Joel Goldstick wrote:
>>>> Am I missing something.
>>> ^
>>> […]
>>> You are missing a leading space character because in the string the
>>> comma was followed by one.
>>
>> I see that now. Performing float on each element of the list will
>> take care of that, or I guess .strip() on each first.
>
> As I showed, .strip() is unnecessary. But float() is always necessary for
> computing the sum and suffices indeed together with s.split() if s is just
> a comma-separated list of numeric strings with optional whitespace leading
> and trailing the comma:
>
> print(sum(map(lambda x: float(x), s.split(',')))
>
> Please trim your quotes to the relevant minimum.
Hm, can you explain what this
lambda x: float(x)
is supposed to achieve? I mean other than to confuse a newbie...
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-12 01:45 +0100 |
| Message-ID | <2606109.fVWkh9SoWk@PointedEars.de> |
| In reply to | #83580 |
Peter Otten wrote:
> Thomas 'PointedEars' Lahn wrote:
>> […] But float() is always necessary for computing the sum and suffices
>> indeed together with s.split() if s is just a comma-separated list of
>> numeric strings with optional whitespace leading and trailing the comma:
>>
>> print(sum(map(lambda x: float(x), s.split(',')))
>>
>> Please trim your quotes to the relevant minimum.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Hm, can you explain what this
>
> lambda x: float(x)
>
> is supposed to achieve? I mean other than to confuse a newbie...
print(sum(map(float, s.split(','))))
suffices in this case, of course.
I could have done without the snide remarks.
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-01-12 11:17 +1100 |
| Message-ID | <mailman.17604.1421021857.18130.python-list@python.org> |
| In reply to | #83577 |
On Mon, Jan 12, 2015 at 11:09 AM, Peter Otten <__peter__@web.de> wrote:
>>
>> print(sum(map(lambda x: float(x), s.split(',')))
>>
>> Please trim your quotes to the relevant minimum.
>
> Hm, can you explain what this
>
> lambda x: float(x)
>
> is supposed to achieve? I mean other than to confuse a newbie...
Maybe he gets paid by the character.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-01-12 11:45 +1100 |
| Message-ID | <54b31929$0$13014$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #83568 |
Thomas 'PointedEars' Lahn wrote:
> This is safer:
>
> | >>> from re import split
> | >>> split(r'\s*,\s*', '1.23, 2.4, 3.123')
> | ['1.23', '2.4', '3.123']
Safer, slower, and unnecessary.
There is no need for the nuclear-powered bulldozer of regular expressions
just to crack this tiny peanut. We can split on commas, and then strip
whitespace:
py> values = " 1.234 , 4.5678, 9.0123 ,4.321,0.9876 "
py> [s.strip() for s in values.split(',')]
['1.234', '4.5678', '9.0123', '4.321', '0.9876']
but in fact, we don't even need that, since float is perfectly happy to
accept strings with leading and trailing spaces:
py> float(' 1.2345 ')
1.2345
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Grant Edwards <invalid@invalid.invalid> |
|---|---|
| Date | 2015-01-11 23:06 +0000 |
| Message-ID | <m8uvm8$omu$1@reader1.panix.com> |
| In reply to | #83566 |
On 2015-01-11, Joel Goldstick <joel.goldstick@gmail.com> wrote:
> That's fine, but its different than your original question. In your
> original question you had a string of floats separated by commas. To
> solve that problem you need to first split the string on the commas:
>
> my_list = "1.23, 2.4, 3.123".split(",")
>
> that will give you ['1.23', '2.4', '3.123']
Well, almost:
$ python
Python 2.7.9 (default, Jan 11 2015, 15:39:24)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> "1.23, 2.4, 3.123".split(",")
['1.23', ' 2.4', ' 3.123']
Note the leating whitespace in two of the elements. In this case, the
leading whitespace is ignored if you pass the values to float():
>>>map(float,"1.23, 2.4, 3.123".split(","))
[1.23, 2.4, 3.123]
Or for you young folks who prefer the more long-winded version:
>>> [float(s) for s in "1.23, 2.4, 3.123".split(",")]
[1.23, 2.4, 3.123]
In other situations, the leading whitespace might matter.
--
Grant
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-12 00:07 +0100 |
| Message-ID | <3233082.KAWmNIKqbW@PointedEars.de> |
| In reply to | #83556 |
Store Makhzan wrote:
> I have this script which can calculate the total of numbers given in a
> string […]
> total = 0
> for c in '0123456789':
> total += int(c)
> print total
>
> […]
> How should I modify this script to find the total of if the numbers given
> in the string form have decimal places? That is, how do I need to modify
> this line: […]
>
> for c in '1.32, 5.32, 4.4, 3.78':
>
> […] to find the total of these given numbers.
The original script already does not do what it advertises. Instead, it
iterates over the characters of the string, attempts to convert each to an
integer and then computes the sum. That is _not_ “calculate the total of
numbers given in a string”.
A solution has been presented, but it is not very pythonic because the
original code was not; that should have been
### Ahh, Gauß ;-)
print(sum(map(lambda x: int(x), list('0123456789'))))
### --------------------------------------------------------------------
Also, it cannot handle non-numeric strings well. Consider this instead:
### --------------------------------------------------------------------
from re import findall
s = '1.32, 5.32, 4.4, 3.78'
print(sum(map(lambda x: float(x), findall(r'-?\d+\.\d+', s))))
### --------------------------------------------------------------------
But if you are sure that except for the comma separator there are only
numeric strings, it is more efficient to use re.split() instead of
re.findall() here.
Aside:
I thought I had more than a fair grasp of regular expressions, but I am
puzzled by
| $ python3
| Python 3.4.2 (default, Dec 27 2014, 13:16:08)
| [GCC 4.9.2] on linux
| >>> from re import findall
| >>> s = '1.32, 5.32, 4.4, 3.78'
| >>> findall(r'-?\d+(\.\d+)?', s)
| ['.32', '.32', '.4', '.78']
Why does this more flexible pattern not work as I expected in Python 3.x,
but virtually everywhere else?
And why this?
| >>> findall(r'-?\d+\.\d+', s)
| ['1.32', '5.32', '4.4', '3.78']
| >>> findall(r'-?\d+(\.\d+)', s)
| ['.32', '.32', '.4', '.78']
Feature? Bug?
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-01-12 00:04 +0000 |
| Message-ID | <mailman.17602.1421021101.18130.python-list@python.org> |
| In reply to | #83574 |
On 11/01/2015 23:07, Thomas 'PointedEars' Lahn wrote:
> Store Makhzan wrote:
>
>> I have this script which can calculate the total of numbers given in a
>> string […]
>> total = 0
>> for c in '0123456789':
>> total += int(c)
>> print total
>>
>> […]
>> How should I modify this script to find the total of if the numbers given
>> in the string form have decimal places? That is, how do I need to modify
>> this line: […]
>>
>> for c in '1.32, 5.32, 4.4, 3.78':
>>
>> […] to find the total of these given numbers.
>
> The original script already does not do what it advertises. Instead, it
> iterates over the characters of the string, attempts to convert each to an
> integer and then computes the sum. That is _not_ “calculate the total of
> numbers given in a string”.
>
> A solution has been presented, but it is not very pythonic because the
> original code was not; that should have been
>
> ### Ahh, Gauß ;-)
> print(sum(map(lambda x: int(x), list('0123456789'))))
> ### --------------------------------------------------------------------
>
> Also, it cannot handle non-numeric strings well. Consider this instead:
>
> ### --------------------------------------------------------------------
> from re import findall
>
> s = '1.32, 5.32, 4.4, 3.78'
> print(sum(map(lambda x: float(x), findall(r'-?\d+\.\d+', s))))
> ### --------------------------------------------------------------------
>
> But if you are sure that except for the comma separator there are only
> numeric strings, it is more efficient to use re.split() instead of
> re.findall() here.
>
>
> Aside:
>
> I thought I had more than a fair grasp of regular expressions, but I am
> puzzled by
>
> | $ python3
> | Python 3.4.2 (default, Dec 27 2014, 13:16:08)
> | [GCC 4.9.2] on linux
> | >>> from re import findall
> | >>> s = '1.32, 5.32, 4.4, 3.78'
> | >>> findall(r'-?\d+(\.\d+)?', s)
> | ['.32', '.32', '.4', '.78']
>
> Why does this more flexible pattern not work as I expected in Python 3.x,
> but virtually everywhere else?
>
> And why this?
>
> | >>> findall(r'-?\d+\.\d+', s)
> | ['1.32', '5.32', '4.4', '3.78']
> | >>> findall(r'-?\d+(\.\d+)', s)
> | ['.32', '.32', '.4', '.78']
>
> Feature? Bug?
>
I can't tell you as I avoid regexes like I avoid the plague. Having
said that I do know that there loads of old bugs on the bug tracker,
many of which are fixed in the "new" regex module that's available here
https://pypi.python.org/pypi/regex/
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.
Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2015-01-12 02:00 +0100 |
| Message-ID | <1596579.yx7AUifxch@PointedEars.de> |
| In reply to | #83579 |
Mark Lawrence wrote:
> On 11/01/2015 23:07, Thomas 'PointedEars' Lahn wrote:
>> I thought I had more than a fair grasp of regular expressions, but I am
>> puzzled by
>>
>> | $ python3
>> | Python 3.4.2 (default, Dec 27 2014, 13:16:08)
>> | [GCC 4.9.2] on linux
>> | >>> from re import findall
>> | >>> s = '1.32, 5.32, 4.4, 3.78'
>> | >>> findall(r'-?\d+(\.\d+)?', s)
>> | ['.32', '.32', '.4', '.78']
>>
>> Why does this more flexible pattern not work as I expected in Python 3.x,
>> but virtually everywhere else?
>>
>> And why this?
>>
>> | >>> findall(r'-?\d+\.\d+', s)
>> | ['1.32', '5.32', '4.4', '3.78']
>> | >>> findall(r'-?\d+(\.\d+)', s)
>> | ['.32', '.32', '.4', '.78']
>>
>> Feature? Bug?
>
> I can't tell you
I know now why I get this result. It is a feature, not a bug:
<https://docs.python.org/3/library/re.html?highlight=findall#re.findall>
|
| re.findall(pattern, string, flags=0)
| Return all non-overlapping matches of pattern in string, as a list of
| strings. The string is scanned left-to-right, and matches are returned
| in the order found. If one or more groups are present in the pattern,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| return a list of groups; this will be a list of tuples if the pattern
^^^^^^^^^^^^^^^^^^^^^^^
| has more than one group. Empty matches are included in the result unless
| they touch the beginning of another match.
A solution is to use non-capturing parentheses:
| >>> findall(r'-?\d+(?:\.\d+)?', '1.32, 5.32, 4.4, 3.78')
| ['1.32', '5.32', '4.4', '3.78']
> as I avoid regexes like I avoid the plague.
You should reconsider. Regular expressions are a powerful tool.
> Having said that I do know that there loads of old bugs on the bug
> tracker, many of which are fixed in the "new" regex module that's
> available here https://pypi.python.org/pypi/regex/
Interesting, thank you.
Please trim your quotes to the relevant minimum next time, though.
--
PointedEars
Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2015-01-12 00:59 +0000 |
| Message-ID | <mailman.17605.1421024362.18130.python-list@python.org> |
| In reply to | #83574 |
On 2015-01-12 00:04, Mark Lawrence wrote:
> On 11/01/2015 23:07, Thomas 'PointedEars' Lahn wrote:
>> Store Makhzan wrote:
>>
>>> I have this script which can calculate the total of numbers given in a
>>> string […]
>>> total = 0
>>> for c in '0123456789':
>>> total += int(c)
>>> print total
>>>
>>> […]
>>> How should I modify this script to find the total of if the numbers given
>>> in the string form have decimal places? That is, how do I need to modify
>>> this line: […]
>>>
>>> for c in '1.32, 5.32, 4.4, 3.78':
>>>
>>> […] to find the total of these given numbers.
>>
>> The original script already does not do what it advertises. Instead, it
>> iterates over the characters of the string, attempts to convert each to an
>> integer and then computes the sum. That is _not_ “calculate the total of
>> numbers given in a string”.
>>
>> A solution has been presented, but it is not very pythonic because the
>> original code was not; that should have been
>>
>> ### Ahh, Gauß ;-)
>> print(sum(map(lambda x: int(x), list('0123456789'))))
>> ### --------------------------------------------------------------------
>>
>> Also, it cannot handle non-numeric strings well. Consider this instead:
>>
>> ### --------------------------------------------------------------------
>> from re import findall
>>
>> s = '1.32, 5.32, 4.4, 3.78'
>> print(sum(map(lambda x: float(x), findall(r'-?\d+\.\d+', s))))
>> ### --------------------------------------------------------------------
>>
>> But if you are sure that except for the comma separator there are only
>> numeric strings, it is more efficient to use re.split() instead of
>> re.findall() here.
>>
>>
>> Aside:
>>
>> I thought I had more than a fair grasp of regular expressions, but I am
>> puzzled by
>>
>> | $ python3
>> | Python 3.4.2 (default, Dec 27 2014, 13:16:08)
>> | [GCC 4.9.2] on linux
>> | >>> from re import findall
>> | >>> s = '1.32, 5.32, 4.4, 3.78'
>> | >>> findall(r'-?\d+(\.\d+)?', s)
>> | ['.32', '.32', '.4', '.78']
>>
>> Why does this more flexible pattern not work as I expected in Python 3.x,
>> but virtually everywhere else?
>>
>> And why this?
>>
>> | >>> findall(r'-?\d+\.\d+', s)
>> | ['1.32', '5.32', '4.4', '3.78']
>> | >>> findall(r'-?\d+(\.\d+)', s)
>> | ['.32', '.32', '.4', '.78']
>>
>> Feature? Bug?
>>
>
> I can't tell you as I avoid regexes like I avoid the plague. Having
> said that I do know that there loads of old bugs on the bug tracker,
> many of which are fixed in the "new" regex module that's available here
> https://pypi.python.org/pypi/regex/
>
It's not a bug.
re.findall returns the capture groups, if present, or the entire match
if there are no capture groups.
In this instance, it's better to use a non-capture group:
findall(r'-?\d+(?:\.\d+)', s)
It's all in the docs! :-)
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-01-12 12:13 +1100 |
| Message-ID | <54b31fb2$0$12978$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #83574 |
Thomas 'PointedEars' Lahn wrote:
> The original script already does not do what it advertises. Instead, it
> iterates over the characters of the string, attempts to convert each to an
> integer and then computes the sum. That is _not_ “calculate the total of
> numbers given in a string”.
Yes, and the second piece of code the Original Poster provided is even
worse:
#Check if a perfect cube
total = 0
for c in ('1.23', '2.4', '3.123'):
print float(c)
total += float(c)
print total
I don't see how adding up some numbers checks whether it is a perfect cube.
I guess this is a good example of this:
At Resolver we've found it useful to short-circuit any doubt
and just refer to comments in code as 'lies'.
http://import-that.dreamwidth.org/956.html
> A solution has been presented, but it is not very pythonic because the
> original code was not; that should have been
>
> ### Ahh, Gauß ;-)
> print(sum(map(lambda x: int(x), list('0123456789'))))
That can be simplified to:
sum(map(int, '0123456789'))
which can then be passed to print() if required.
> Also, it cannot handle non-numeric strings well. Consider this instead:
The OP hasn't specified whether or not he has to deal with non-numeric
strings, or how he wants to deal with them. But my guess is that he
actually doesn't want strings at all, and needs to be taught how to work
with lists of floats and/or ints.
> ### --------------------------------------------------------------------
> from re import findall
>
> s = '1.32, 5.32, 4.4, 3.78'
> print(sum(map(lambda x: float(x), findall(r'-?\d+\.\d+', s))))
> ### --------------------------------------------------------------------
Consider this:
py> s = '123^%#@1.2abc, %#$@2.1&*%^'
py> print(sum(map(lambda x: float(x), findall(r'-?\d+\.\d+', s))))
3.3
If your aim is just to hide the fact that you have bad data, then the regex
solution "works". Many beginners think that their job as a programmer is to
stop the program from raising an exception no matter what. But I suggest
that Postel's Law:
Be conservative in what you emit, and liberal in what you accept.
shouldn't apply here. I don't think any reasonable person would expect that
the string "123^%#@1.2abc" should be treated as 1.2.
> Aside:
>
> I thought I had more than a fair grasp of regular expressions, but I am
> puzzled by
>
> | $ python3
> | Python 3.4.2 (default, Dec 27 2014, 13:16:08)
> | [GCC 4.9.2] on linux
> | >>> from re import findall
> | >>> s = '1.32, 5.32, 4.4, 3.78'
> | >>> findall(r'-?\d+(\.\d+)?', s)
> | ['.32', '.32', '.4', '.78']
>
> Why does this more flexible pattern not work as I expected in Python 3.x,
> but virtually everywhere else?
This is documented by findall:
py> help(findall)
Help on function findall in module re:
findall(pattern, string, flags=0)
Return a list of all non-overlapping matches in the string.
If one or more groups are present in the pattern, return a
list of groups; this will be a list of tuples if the pattern
has more than one group.
Empty matches are included in the result.
--
Steven
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web