0

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)

0

7 Answers 7

2

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] 
Sign up to request clarification or add additional context in comments.

1 Comment

Why the [i for i in get()]? This needlessly allocates a list, and i for i in is a tautology.
1

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] 

Comments

1

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] 

3 Comments

or even shorter: get = lambda: [0]*3.
@Space_C0wb0y Nope that's shorter in code, but creates a list instead of a generator. For large values of 3, your solution allocates lots of potentially unneeded memory.
@philhag I like the idea of "large values of 3" = that could make maths interesting :-)
1

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] 

Comments

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] 

Comments

0

You could try this instead:

def get(): return [0] * 3 r = [] r.extend(get()) r [0, 0, 0] 

Comments

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 

1 Comment

i already have a function that yield [someint] and i can't modify it

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.