Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #105389 > unrolled thread
| Started by | Maurice <mauricioliveiraguarda@gmail.com> |
|---|---|
| First post | 2016-03-21 11:26 -0700 |
| Last post | 2016-03-22 21:49 +1100 |
| Articles | 15 — 10 participants |
Back to article view | Back to comp.lang.python
Convert list to another form but providing same information Maurice <mauricioliveiraguarda@gmail.com> - 2016-03-21 11:26 -0700
Re: Convert list to another form but providing same information Maurice <mauricioliveiraguarda@gmail.com> - 2016-03-21 11:30 -0700
Re: Convert list to another form but providing same information Mark Lawrence <breamoreboy@yahoo.co.uk> - 2016-03-21 19:24 +0000
Re: Convert list to another form but providing same information anantguptadbl@gmail.com - 2016-03-22 07:23 -0700
Re: Convert list to another form but providing same information Mark Lawrence <breamoreboy@yahoo.co.uk> - 2016-03-21 19:21 +0000
Re: Convert list to another form but providing same information Peter Otten <__peter__@web.de> - 2016-03-21 20:22 +0100
Re: Convert list to another form but providing same information Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-03-21 20:03 +0000
Re: Convert list to another form but providing same information Ian Kelly <ian.g.kelly@gmail.com> - 2016-03-21 14:12 -0600
Re: Convert list to another form but providing same information Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-03-22 00:31 +0000
Re: Convert list to another form but providing same information Chris Angelico <rosuav@gmail.com> - 2016-03-22 11:58 +1100
Re: Convert list to another form but providing same information Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-03-22 15:34 +1100
Re: Convert list to another form but providing same information Ian Kelly <ian.g.kelly@gmail.com> - 2016-03-21 14:14 -0600
Re: Convert list to another form but providing same information Steven D'Aprano <steve@pearwood.info> - 2016-03-22 11:13 +1100
Re: Convert list to another form but providing same information Paul Rubin <no.email@nospam.invalid> - 2016-03-21 18:35 -0700
Re: Convert list to another form but providing same information Steven D'Aprano <steve@pearwood.info> - 2016-03-22 21:49 +1100
| From | Maurice <mauricioliveiraguarda@gmail.com> |
|---|---|
| Date | 2016-03-21 11:26 -0700 |
| Subject | Convert list to another form but providing same information |
| Message-ID | <1010f2cb-21f9-495b-8af4-03ad209b4c1e@googlegroups.com> |
Hello, hope everything is okay. I think someone might have dealt with a similar issue I'm having.
Basically I wanna do the following:
I have a list such [6,19,19,21,21,21] (FYI this is the item of a certain key in the dictionary)
And I need to convert it to a list of 32 elements (meaning days of the month however first element ie index 0 or day zero has no meaning - keeping like that for simplicity's sake).
Therefore the resulting list should be:
[0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
So the list index should tell how many occurrences of a certain day in the original list.
My attempt:
weirdList = [[0]*32]*len(dict_days) #list's length should be how many keys in the dict.
counter = 0
k = 0
for key in dict_days.keys():
for i in range(1,32):
if i in dict_days[key]:
counter = dict_days[key].count(i)
weirdList[k][i] = counter
dict_days[key] = weirdList[k]
k+=1
However it does not work. weirdList seems to be always the same?
Thanks in advance.
[toc] | [next] | [standalone]
| From | Maurice <mauricioliveiraguarda@gmail.com> |
|---|---|
| Date | 2016-03-21 11:30 -0700 |
| Message-ID | <eb002b45-6b6b-422c-8a9b-ee36c95109ca@googlegroups.com> |
| In reply to | #105389 |
Just figured why: If I type this on the kernel: weirdList = [[0]*3]*5 weirdList Out[257]: [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] weirdList[0][0] = 1 weirdList Out[259]: [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] All first elements of the sublists also changes. I dunno why...
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2016-03-21 19:24 +0000 |
| Message-ID | <mailman.459.1458588607.12893.python-list@python.org> |
| In reply to | #105390 |
On 21/03/2016 18:30, Maurice wrote: > Just figured why: > > If I type this on the kernel: > > weirdList = [[0]*3]*5 > > weirdList > Out[257]: [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] > > weirdList[0][0] = 1 > > weirdList > Out[259]: [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] > > All first elements of the sublists also changes. I dunno why... > https://docs.python.org/3/faq/programming.html#why-did-changing-list-y-also-change-list-x -- 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 | anantguptadbl@gmail.com |
|---|---|
| Date | 2016-03-22 07:23 -0700 |
| Message-ID | <1ec91e1c-9d0e-448b-a7b6-194ac105f8e2@googlegroups.com> |
| In reply to | #105390 |
On Tuesday, March 22, 2016 at 12:01:10 AM UTC+5:30, Maurice wrote: > Just figured why: > > If I type this on the kernel: > > weirdList = [[0]*3]*5 > > weirdList > Out[257]: [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] > > weirdList[0][0] = 1 > > weirdList > Out[259]: [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] > > All first elements of the sublists also changes. I dunno why... When we write [[0] * 3] * 5, the [0] * 3 list is repeated 5 times its something like list,list,list,list,list if we change the 1st element of list, it gets reflected on all the 5 copies
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2016-03-21 19:21 +0000 |
| Message-ID | <mailman.457.1458588135.12893.python-list@python.org> |
| In reply to | #105389 |
On 21/03/2016 18:26, Maurice wrote:
> Hello, hope everything is okay. I think someone might have dealt with a similar issue I'm having.
>
> Basically I wanna do the following:
>
> I have a list such [6,19,19,21,21,21] (FYI this is the item of a certain key in the dictionary)
>
> And I need to convert it to a list of 32 elements (meaning days of the month however first element ie index 0 or day zero has no meaning - keeping like that for simplicity's sake).
> Therefore the resulting list should be:
> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
>
> So the list index should tell how many occurrences of a certain day in the original list.
>
> My attempt:
>
> weirdList = [[0]*32]*len(dict_days) #list's length should be how many keys in the dict.
>
> counter = 0
> k = 0
> for key in dict_days.keys():
> for i in range(1,32):
> if i in dict_days[key]:
> counter = dict_days[key].count(i)
> weirdList[k][i] = counter
> dict_days[key] = weirdList[k]
> k+=1
>
> However it does not work. weirdList seems to be always the same?
>
> Thanks in advance.
>
>>> from collections import Counter
>>> counts = Counter([6,19,19,21,21,21])
>>> counts
Counter({21: 3, 19: 2, 6: 1})
>>> weird_list = [0]*32
>>> weird_list
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0]
>>> for index, count in counts.items():
... weird_list[index] = count
...
>>> weird_list
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0]
--
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 | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-03-21 20:22 +0100 |
| Message-ID | <mailman.458.1458588144.12893.python-list@python.org> |
| In reply to | #105389 |
Maurice wrote:
> Hello, hope everything is okay. I think someone might have dealt with a
> similar issue I'm having.
>
> Basically I wanna do the following:
>
> I have a list such [6,19,19,21,21,21] (FYI this is the item of a certain
> key in the dictionary)
>
> And I need to convert it to a list of 32 elements (meaning days of the
> month however first element ie index 0 or day zero has no meaning -
> keeping like that for simplicity's sake). Therefore the resulting list
> should be:
> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
>
> So the list index should tell how many occurrences of a certain day in the
> original list.
>
> My attempt:
>
> weirdList = [[0]*32]*len(dict_days) #list's length should be how many keys
> in the dict.
Rewrite the above as
inner = [0] * 32
weirdList = [inner] * len(dict_days)
Now it should be clearer that weirdList is
[inner, inner, inner, ...]
i. e. len(dict_days) times the same list of 32 zeros. When you modify
weirdList[0] you also modify weirdList[1] etc. because these are the
actually the same list.
For the inner list this is not a problem because 0 is immutable, so you can
only replace it. If the inner list contained a mutable object you'd see the
same "weird" behaviour you see for the outer list.
The fix is to use multiple inner lists:
not_so_weirdList = [[0]*32 for _ in range(len(dict_days))]
> counter = 0
> k = 0
> for key in dict_days.keys():
> for i in range(1,32):
> if i in dict_days[key]:
> counter = dict_days[key].count(i)
> weirdList[k][i] = counter
> dict_days[key] = weirdList[k]
> k+=1
>
> However it does not work. weirdList seems to be always the same?
Instead of the list you could use a counter and get basically the same
interface as long as you ensure that the second index satisfies 0<=index<32:
import collections
for key, values in dict_days.items():
dict_days[key] = collections.Counter(values)
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-03-21 20:03 +0000 |
| Message-ID | <87bn67oayt.fsf@bsb.me.uk> |
| In reply to | #105389 |
Maurice <mauricioliveiraguarda@gmail.com> writes:
> Hello, hope everything is okay. I think someone might have dealt with
> a similar issue I'm having.
>
> Basically I wanna do the following:
>
> I have a list such [6,19,19,21,21,21] (FYI this is the item of a
>certain key in the dictionary)
>
> And I need to convert it to a list of 32 elements (meaning days of the
> month however first element ie index 0 or day zero has no meaning -
> keeping like that for simplicity's sake).
> Therefore the resulting list should be:
> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
How about
reduce(lambda counts, day: counts[:day] + [counts[day]+1] + counts[day+1:],
days, [0]*32)
? (reduce is in functools).
Not efficient, but sometimes you just want to the job done.
More efficient would be:
def inc_day(counts, day): counts[day] += 1; return counts
reduce(inc_day, days, [0]*32)
For experts here: why can't I write a lambda that has a statement in it
(actually I wanted two: lambda l, i: l[i] += 1; return l)?
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-03-21 14:12 -0600 |
| Message-ID | <mailman.461.1458591209.12893.python-list@python.org> |
| In reply to | #105401 |
On Mon, Mar 21, 2016 at 2:03 PM, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote: > For experts here: why can't I write a lambda that has a statement in it > (actually I wanted two: lambda l, i: l[i] += 1; return l)? https://docs.python.org/3/faq/design.html#why-can-t-lambda-expressions-contain-statements
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-03-22 00:31 +0000 |
| Message-ID | <87oaa7mjyh.fsf@bsb.me.uk> |
| In reply to | #105402 |
Ian Kelly <ian.g.kelly@gmail.com> writes:
> On Mon, Mar 21, 2016 at 2:03 PM, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> For experts here: why can't I write a lambda that has a statement in it
>> (actually I wanted two: lambda l, i: l[i] += 1; return l)?
>
> https://docs.python.org/3/faq/design.html#why-can-t-lambda-expressions-contain-statements
Thanks. That makes it clear that it's just for syntactic and not
semantic reasons.
However, the explanation ("because Python’s syntactic framework can't
handle statements nested inside expressions") seemed, at first, to be
saying you can't because you can't! But the term "syntactic framework"
hints that it's not really just an arbitrary choice -- that this is
something about the way Python is parsed that make this choice
inevitable. Is it to do with the way that indentation has a syntactic
role?
To phrase my question in terms of syntax, why is the : in lambda
followed by a test (the top-level production for an expression in the
grammar) but the : in a function definition is followed by a suite? I
expected them to be both a suite, but presumably something goes horribly
wrong if that were done. Now I'm wondering what.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-03-22 11:58 +1100 |
| Message-ID | <mailman.477.1458608322.12893.python-list@python.org> |
| In reply to | #105423 |
On Tue, Mar 22, 2016 at 11:31 AM, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> However, the explanation ("because Python’s syntactic framework can't
> handle statements nested inside expressions") seemed, at first, to be
> saying you can't because you can't! But the term "syntactic framework"
> hints that it's not really just an arbitrary choice -- that this is
> something about the way Python is parsed that make this choice
> inevitable. Is it to do with the way that indentation has a syntactic
> role?
>
> To phrase my question in terms of syntax, why is the : in lambda
> followed by a test (the top-level production for an expression in the
> grammar) but the : in a function definition is followed by a suite? I
> expected them to be both a suite, but presumably something goes horribly
> wrong if that were done. Now I'm wondering what.
A "suite" is a series of statements - in common parlance, a block of
code. A "test" is a type of expression (there are a variety of these
kind of things, and they define operator precedence).
Part of the trickiness of permitting statements inside expressions is
that it would get confusing - not that it'd be truly ambiguous and
impossible to parse, but that small errors could result in peculiar
misinterpretations of subsequent code, which means the error messages
would be harder to understand. There are already a few places like
that:
functioncall( # ) # oops, forgot the close parenthesis
name = value
othername = othervalue
You'll get a SyntaxError on the last line, despite it being
functionally identical to the second. And it's just "invalid syntax",
the most completely unhelpful message. (This situation is considered
worthwhile, though. Named arguments and assignment both make way too
much sense to break one of them.) Now imagine if every "lambda" in the
code could result in the same kind of thing; currently, the keyword
"lambda" must be followed by a (possibly empty) argument list and then
an expression, which must either be entirely within one line, or have
parentheses around it. If, instead, "lambda x:" introduced a suite,
you'd have errors coming up much further down.
Having full statement syntax inside an expression isn't always even a
benefit. It's often a major cost to readability - just have a look at
a big pile of JavaScript callback code some time. (Although, to be
fair, function() {...} isn't the only readability problem there.) And
it has a debugging cost that gets significantly higher when you don't
have braces to delimit blocks.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-03-22 15:34 +1100 |
| Message-ID | <56f0cb6d$0$1607$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #105423 |
On Tuesday 22 March 2016 11:31, Ben Bacarisse wrote:
> Ian Kelly <ian.g.kelly@gmail.com> writes:
>
>> On Mon, Mar 21, 2016 at 2:03 PM, Ben Bacarisse <ben.usenet@bsb.me.uk>
>> wrote:
>>> For experts here: why can't I write a lambda that has a statement in it
>>> (actually I wanted two: lambda l, i: l[i] += 1; return l)?
>>
>> https://docs.python.org/3/faq/design.html#why-can-t-lambda-expressions-
contain-statements
>
> Thanks. That makes it clear that it's just for syntactic and not
> semantic reasons.
>
> However, the explanation ("because Python’s syntactic framework can't
> handle statements nested inside expressions") seemed, at first, to be
> saying you can't because you can't! But the term "syntactic framework"
> hints that it's not really just an arbitrary choice -- that this is
> something about the way Python is parsed that make this choice
> inevitable. Is it to do with the way that indentation has a syntactic
> role?
Don't ask me for a link, because I'm lazy, but this has been discussed like
a bazillion times in the past, here, and on the Python-Ideas and Python-Dev
mailing lists. No offense intended, but if you want definitive statements
from the core developers, you can google for them :-)
But in a nutshell, there are four reasons for the limitation on Python's
lambda statement:
- The use of indentation makes it hard to insert arbitrary statements into
an expression without confusing the parser.
- Guido has a strict rule that Python's syntax must be parsable using a
relatively simply parser. A LL(1) parser, if I remember correctly. So none
of the fancy tricks and hard-to-understand syntax rules that (say) C++ uses.
- Given those limitations, nobody has been able to come up with syntax that
has broad support.
- And besides, quite a large number of people believe that limiting lambda
to simple, single-expression cases is a feature, not a bug.
Nobody has quite ruled out multi-statement lambda, or code blocks, but after
20+ years of people trying to find syntax which works but isn't hated, and
failing, I think it's probably safe to say it isn't going to happen.
--
Steve
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-03-21 14:14 -0600 |
| Message-ID | <mailman.462.1458591310.12893.python-list@python.org> |
| In reply to | #105401 |
On Mon, Mar 21, 2016 at 2:12 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote: > On Mon, Mar 21, 2016 at 2:03 PM, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote: >> For experts here: why can't I write a lambda that has a statement in it >> (actually I wanted two: lambda l, i: l[i] += 1; return l)? > > https://docs.python.org/3/faq/design.html#why-can-t-lambda-expressions-contain-statements tl;dr: If you want a function with a statement in it, use def, not lambda.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-03-22 11:13 +1100 |
| Message-ID | <56f08e3f$0$1619$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #105389 |
On Tue, 22 Mar 2016 05:26 am, Maurice wrote:
> I have a list such [6,19,19,21,21,21] (FYI this is the item of a certain
> key in the dictionary)
>
> And I need to convert it to a list of 32 elements (meaning days of the
> month however first element ie index 0 or day zero has no meaning -
> keeping like that for simplicity's sake). Therefore the resulting list
> should be:
> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
>
> So the list index should tell how many occurrences of a certain day in the
> original list.
the_list = [6,19,19,21,21,21]
days = [0]*32
for item in the_list:
days[item] += 1
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-03-21 18:35 -0700 |
| Message-ID | <87twjzz44v.fsf@jester.gateway.pace.com> |
| In reply to | #105389 |
Maurice <mauricioliveiraguarda@gmail.com> writes:
> I have a list such [6,19,19,21,21,21]
> Therefore the resulting list should be:
> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
Rather than a sparse list you'd typically want a dictionary (untested):
from collections import defaultdict
the_list = [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
...
days = defaultdict(int)
for t in the_list:
days[t] += 1
this results in days being the defaultdict { 6:1, 19:2, 21:3 }.
defaultdict is a special type of dictionary where if you try to access a
non-existent element, it gets created and initialized with the data
constructor you made it with. In this case the data constructor is int,
and int() makes the number 0, so the defaultdict elements are
initialized to 0.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-03-22 21:49 +1100 |
| Message-ID | <56f12322$0$1607$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #105432 |
On Tue, 22 Mar 2016 12:35 pm, Paul Rubin wrote:
> Maurice <mauricioliveiraguarda@gmail.com> writes:
>> I have a list such [6,19,19,21,21,21]
>> Therefore the resulting list should be:
>> [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
>
> Rather than a sparse list you'd typically want a dictionary (untested):
>
> from collections import defaultdict
> the_list = [0,0,0,0,0,0,1,0,0,0...,2,0,3,0...0]
> ...
> days = defaultdict(int)
> for t in the_list:
> days[t] += 1
>
> this results in days being the defaultdict { 6:1, 19:2, 21:3 }.
For just 3 items out of 32, doing this as an optimisation is barely worth
it. Using Python 3.4, I get 168 bytes for the list solution and 152 bytes
for a default dict solution:
py> print(days)
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0]
py> sys.getsizeof(days)
168
py> from collections import defaultdict
py> d = defaultdict(int)
py> d.update({ 6:1, 19:2, 21:3 })
py> sys.getsizeof(d)
152
By all means use whichever solution suits you best, but don't expect to save
much memory in a "spare array" of only 32 items :-)
--
Steven
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web