开发者

python list confusion

hi i have a situation like this:

>>> def get():
...     for i in range(3):
...             yield [0]
... 

and i want to get this: [0,0,0]

my code now works in this way:

>>> r = []
>>> r.extend(i[0开发者_如何学运维] for i in get())
>>> r
[0, 0, 0]

but i don't like i[0].. some advice?

(i'm on python3)


Your code looks very strange, but I assume it's very simplified. If it's just about getting rid of the i[0], do this:

>>> def get():
...     for i in range(3):
...             yield 0
... 
>>> r = []
>>> r.extend(get())
>>> r
[0, 0, 0]


r.extend(i[0] for i in get())

This kind of imperative code (stateful, with inplace updates) is asking for trouble. That seems the canonical use for a functional flatten (concat):

from itertools import chain

def flatten(listOfLists):
    return chain.from_iterable(listOfLists)

def get():
    for i in range(3):
        yield [0]

print(list(flatten(get())))
# [0, 0, 0]


To me, this looks like get can only ever return a list of length 1. If that's the case, drop the braces:

>>> def get():
...     for i in range(3):
...             yield 0
>>> # Or, shorter ...
>>> get = lambda: (0 for i in range(3))
>>> r = []
>>> r.extend(get())
>>> r
[0, 0, 0]


The reason you are having to use i[0] is because get() is a generator that returns a list of size 1 every time it is called. So your code i[0] for i in get() is the same as i[0] for i in ([0],[0],[0]). The reason your code works is that i[0] gets the first element off the returned element which is itself the list [0].

What I gather from your question is that you want to have i for i in [0,0,0]. As mentioned in other answers this can be achieved by changing you generator to yield the int 0 instead of the list [0]. You can see the result of the generator in the following example code:

>>> for i in get():
...   print("i={} and i[0]={}".format(i, i[0]))
... 
i=[0] and i[0]=0
i=[0] and i[0]=0
i=[0] and i[0]=0

As you can see, your generator returns a [0] every iteration and that is the reason you have to use i[0] to get the first element of each list.

Also, since r is just the results of the generator, you can simplify by just doing the following:

>>> def gen():
...   for i in range(3):
...     yield 0
... 
>>> r = list(gen())
>>> r
[0, 0, 0]


Don't yield an array if you don't want one:

>>> def get():
...  for i in range(3):
...   yield 0
... 
>>> r = []
>>> r.extend(i for i in get())
>>> r
[0, 0, 0]


You could try this instead:

def get():
    return [0] * 3

r = [] 
r.extend(get())
r
[0, 0, 0]


???

def get():
    for i in xrange(3):
        yield 0

r = list(get())

print r

or

gen = (0 for i in xrange(3))

r = list(gen)

print r
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜