List comprehension of tuple gets me a generator - why and how to modify?
up vote
2
down vote
favorite
I am going through the exercises of this site https://anandology.com/python-practice-book/working-with-data.html when I tried to recreate the zip function through list comprehension.
Now I created this function. But instead of getting a list I get a generator :-(
def zipp (liste1,liste2):
length= len(liste1)
zipped=
[zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
return zipped
I searched a little in here and found this:
Python: why does list comprehension produce a generator?
Accordingly I used the "tuple" statement already but to no awail.
I have no idea why I get a generator even with the tuple() inserted.
So my questions:
- why?
- What do I need to change or where can I read/hear more to get "enlightened" myself?
- How could I use the generator to get the result? (or where can I read about this?)
Thanks.
edit: The result I expect is list of tuple with member of each list in it. This I what I should get:
zipp([1, 2, 3], ["a", "b", "c"])
-> [(1, "a"), (2, "b"), (3, "c")]
python generator list-comprehension
|
show 11 more comments
up vote
2
down vote
favorite
I am going through the exercises of this site https://anandology.com/python-practice-book/working-with-data.html when I tried to recreate the zip function through list comprehension.
Now I created this function. But instead of getting a list I get a generator :-(
def zipp (liste1,liste2):
length= len(liste1)
zipped=
[zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
return zipped
I searched a little in here and found this:
Python: why does list comprehension produce a generator?
Accordingly I used the "tuple" statement already but to no awail.
I have no idea why I get a generator even with the tuple() inserted.
So my questions:
- why?
- What do I need to change or where can I read/hear more to get "enlightened" myself?
- How could I use the generator to get the result? (or where can I read about this?)
Thanks.
edit: The result I expect is list of tuple with member of each list in it. This I what I should get:
zipp([1, 2, 3], ["a", "b", "c"])
-> [(1, "a"), (2, "b"), (3, "c")]
python generator list-comprehension
4
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be afor
loop.
– roganjosh
Nov 21 at 16:54
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 at 16:57
1
List comprehensions can mutate mutable objects as though the list comprehension was a regularfor
loop. So, I could use a list comprehension like so;my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would bemy_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.
– roganjosh
Nov 21 at 18:59
1
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just bemy_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point
– roganjosh
Nov 21 at 19:04
|
show 11 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am going through the exercises of this site https://anandology.com/python-practice-book/working-with-data.html when I tried to recreate the zip function through list comprehension.
Now I created this function. But instead of getting a list I get a generator :-(
def zipp (liste1,liste2):
length= len(liste1)
zipped=
[zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
return zipped
I searched a little in here and found this:
Python: why does list comprehension produce a generator?
Accordingly I used the "tuple" statement already but to no awail.
I have no idea why I get a generator even with the tuple() inserted.
So my questions:
- why?
- What do I need to change or where can I read/hear more to get "enlightened" myself?
- How could I use the generator to get the result? (or where can I read about this?)
Thanks.
edit: The result I expect is list of tuple with member of each list in it. This I what I should get:
zipp([1, 2, 3], ["a", "b", "c"])
-> [(1, "a"), (2, "b"), (3, "c")]
python generator list-comprehension
I am going through the exercises of this site https://anandology.com/python-practice-book/working-with-data.html when I tried to recreate the zip function through list comprehension.
Now I created this function. But instead of getting a list I get a generator :-(
def zipp (liste1,liste2):
length= len(liste1)
zipped=
[zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
return zipped
I searched a little in here and found this:
Python: why does list comprehension produce a generator?
Accordingly I used the "tuple" statement already but to no awail.
I have no idea why I get a generator even with the tuple() inserted.
So my questions:
- why?
- What do I need to change or where can I read/hear more to get "enlightened" myself?
- How could I use the generator to get the result? (or where can I read about this?)
Thanks.
edit: The result I expect is list of tuple with member of each list in it. This I what I should get:
zipp([1, 2, 3], ["a", "b", "c"])
-> [(1, "a"), (2, "b"), (3, "c")]
python generator list-comprehension
python generator list-comprehension
edited Nov 21 at 17:02
asked Nov 21 at 16:53
Andreas K.
116211
116211
4
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be afor
loop.
– roganjosh
Nov 21 at 16:54
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 at 16:57
1
List comprehensions can mutate mutable objects as though the list comprehension was a regularfor
loop. So, I could use a list comprehension like so;my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would bemy_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.
– roganjosh
Nov 21 at 18:59
1
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just bemy_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point
– roganjosh
Nov 21 at 19:04
|
show 11 more comments
4
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be afor
loop.
– roganjosh
Nov 21 at 16:54
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 at 16:57
1
List comprehensions can mutate mutable objects as though the list comprehension was a regularfor
loop. So, I could use a list comprehension like so;my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would bemy_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.
– roganjosh
Nov 21 at 18:59
1
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just bemy_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point
– roganjosh
Nov 21 at 19:04
4
4
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be a
for
loop.– roganjosh
Nov 21 at 16:54
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be a
for
loop.– roganjosh
Nov 21 at 16:54
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
1
1
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 at 16:57
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 at 16:57
1
1
List comprehensions can mutate mutable objects as though the list comprehension was a regular
for
loop. So, I could use a list comprehension like so; my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would be my_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.– roganjosh
Nov 21 at 18:59
List comprehensions can mutate mutable objects as though the list comprehension was a regular
for
loop. So, I could use a list comprehension like so; my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would be my_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.– roganjosh
Nov 21 at 18:59
1
1
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just be
my_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point– roganjosh
Nov 21 at 19:04
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just be
my_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point– roganjosh
Nov 21 at 19:04
|
show 11 more comments
2 Answers
2
active
oldest
votes
up vote
2
down vote
you're putting a generator in your object:
tuple(liste1[i], liste2[i]) for i in range(length)
(and tuple
doesn't work too, just remove it....)
(and don't use comprehensions for side effects)
The best way would be to rewrite it completely using a list comprehension which actually returns something, as list comprehensions are supposed to, taking the min of both lengths to fully emulate zip
:
def zipp (liste1,liste2):
return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]
classic loop version (no comprehensions)
def zipp (liste1,liste2):
result =
for i in range(min(len(liste1),len(liste2))):
result.append((liste1[i], liste2[i]))
return result
of course this is nothing else than list(zip(liste1,liste2))
(forcing iteration on zip
)
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
add a comment |
up vote
1
down vote
trying to answer your questions...
1.- why?
A: As many have mention, you return the zipped
list as a list generators within the list comprehension [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
, not a nice way of doing by the way. that's why you get those generators.
2.- What do I need to change or where can I read/hear more to get "enlightened" myself?
A: If you still want to do that way, you only have to append the two items, by moving the parenthesis and removing the tuple function, like so:
def zipp (liste1, liste2):
length = len(liste1)
zipped =
[zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ] # not the best way, but still works. This created list is never used.
return zipped
then it's possible to return the list
zipp([1,2,3], ['a','b','c'])
Note that this asumes both list have same length. Otherwise you have to choose one (like you are doing) or finding the minimum of both lengths (it's also posible to choose the longest and fill with whatever it's needed):
min(len(liste1), len(liste2))
3.- How could I use the generator to get the result?
A: For it to be a generator you need to yield the nedeed value:
def zipp2 (liste1,liste2):
i = 0
minval = min(len(liste1), len(liste2))
while i< minval:
yield (liste1[i], liste2[i])
i += 1
# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
print(p)
and get the results...
<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
you're putting a generator in your object:
tuple(liste1[i], liste2[i]) for i in range(length)
(and tuple
doesn't work too, just remove it....)
(and don't use comprehensions for side effects)
The best way would be to rewrite it completely using a list comprehension which actually returns something, as list comprehensions are supposed to, taking the min of both lengths to fully emulate zip
:
def zipp (liste1,liste2):
return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]
classic loop version (no comprehensions)
def zipp (liste1,liste2):
result =
for i in range(min(len(liste1),len(liste2))):
result.append((liste1[i], liste2[i]))
return result
of course this is nothing else than list(zip(liste1,liste2))
(forcing iteration on zip
)
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
add a comment |
up vote
2
down vote
you're putting a generator in your object:
tuple(liste1[i], liste2[i]) for i in range(length)
(and tuple
doesn't work too, just remove it....)
(and don't use comprehensions for side effects)
The best way would be to rewrite it completely using a list comprehension which actually returns something, as list comprehensions are supposed to, taking the min of both lengths to fully emulate zip
:
def zipp (liste1,liste2):
return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]
classic loop version (no comprehensions)
def zipp (liste1,liste2):
result =
for i in range(min(len(liste1),len(liste2))):
result.append((liste1[i], liste2[i]))
return result
of course this is nothing else than list(zip(liste1,liste2))
(forcing iteration on zip
)
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
add a comment |
up vote
2
down vote
up vote
2
down vote
you're putting a generator in your object:
tuple(liste1[i], liste2[i]) for i in range(length)
(and tuple
doesn't work too, just remove it....)
(and don't use comprehensions for side effects)
The best way would be to rewrite it completely using a list comprehension which actually returns something, as list comprehensions are supposed to, taking the min of both lengths to fully emulate zip
:
def zipp (liste1,liste2):
return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]
classic loop version (no comprehensions)
def zipp (liste1,liste2):
result =
for i in range(min(len(liste1),len(liste2))):
result.append((liste1[i], liste2[i]))
return result
of course this is nothing else than list(zip(liste1,liste2))
(forcing iteration on zip
)
you're putting a generator in your object:
tuple(liste1[i], liste2[i]) for i in range(length)
(and tuple
doesn't work too, just remove it....)
(and don't use comprehensions for side effects)
The best way would be to rewrite it completely using a list comprehension which actually returns something, as list comprehensions are supposed to, taking the min of both lengths to fully emulate zip
:
def zipp (liste1,liste2):
return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]
classic loop version (no comprehensions)
def zipp (liste1,liste2):
result =
for i in range(min(len(liste1),len(liste2))):
result.append((liste1[i], liste2[i]))
return result
of course this is nothing else than list(zip(liste1,liste2))
(forcing iteration on zip
)
edited Nov 21 at 17:20
answered Nov 21 at 17:05
Jean-François Fabre
98.8k951107
98.8k951107
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
add a comment |
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
I would just add the straight-forward for-loop way as well, just to illustrate what list-comprehensions are actually doing
– juanpa.arrivillaga
Nov 21 at 17:13
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:
[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
Your zipp solution is actually what I was looking for! Thanks. Btw, I fixed mine too, but it got even uglier:
[zipped.append([tuple([liste1[i], liste2[i]]) for i in range(length)])]
or without tuple:zipped.append([(liste1[i], liste2[i]) for i in range(length)])
– Andreas K.
Nov 21 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
don't append to a list with a list, extend it.
– Jean-François Fabre
Nov 21 at 19:29
add a comment |
up vote
1
down vote
trying to answer your questions...
1.- why?
A: As many have mention, you return the zipped
list as a list generators within the list comprehension [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
, not a nice way of doing by the way. that's why you get those generators.
2.- What do I need to change or where can I read/hear more to get "enlightened" myself?
A: If you still want to do that way, you only have to append the two items, by moving the parenthesis and removing the tuple function, like so:
def zipp (liste1, liste2):
length = len(liste1)
zipped =
[zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ] # not the best way, but still works. This created list is never used.
return zipped
then it's possible to return the list
zipp([1,2,3], ['a','b','c'])
Note that this asumes both list have same length. Otherwise you have to choose one (like you are doing) or finding the minimum of both lengths (it's also posible to choose the longest and fill with whatever it's needed):
min(len(liste1), len(liste2))
3.- How could I use the generator to get the result?
A: For it to be a generator you need to yield the nedeed value:
def zipp2 (liste1,liste2):
i = 0
minval = min(len(liste1), len(liste2))
while i< minval:
yield (liste1[i], liste2[i])
i += 1
# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
print(p)
and get the results...
<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
add a comment |
up vote
1
down vote
trying to answer your questions...
1.- why?
A: As many have mention, you return the zipped
list as a list generators within the list comprehension [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
, not a nice way of doing by the way. that's why you get those generators.
2.- What do I need to change or where can I read/hear more to get "enlightened" myself?
A: If you still want to do that way, you only have to append the two items, by moving the parenthesis and removing the tuple function, like so:
def zipp (liste1, liste2):
length = len(liste1)
zipped =
[zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ] # not the best way, but still works. This created list is never used.
return zipped
then it's possible to return the list
zipp([1,2,3], ['a','b','c'])
Note that this asumes both list have same length. Otherwise you have to choose one (like you are doing) or finding the minimum of both lengths (it's also posible to choose the longest and fill with whatever it's needed):
min(len(liste1), len(liste2))
3.- How could I use the generator to get the result?
A: For it to be a generator you need to yield the nedeed value:
def zipp2 (liste1,liste2):
i = 0
minval = min(len(liste1), len(liste2))
while i< minval:
yield (liste1[i], liste2[i])
i += 1
# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
print(p)
and get the results...
<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
add a comment |
up vote
1
down vote
up vote
1
down vote
trying to answer your questions...
1.- why?
A: As many have mention, you return the zipped
list as a list generators within the list comprehension [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
, not a nice way of doing by the way. that's why you get those generators.
2.- What do I need to change or where can I read/hear more to get "enlightened" myself?
A: If you still want to do that way, you only have to append the two items, by moving the parenthesis and removing the tuple function, like so:
def zipp (liste1, liste2):
length = len(liste1)
zipped =
[zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ] # not the best way, but still works. This created list is never used.
return zipped
then it's possible to return the list
zipp([1,2,3], ['a','b','c'])
Note that this asumes both list have same length. Otherwise you have to choose one (like you are doing) or finding the minimum of both lengths (it's also posible to choose the longest and fill with whatever it's needed):
min(len(liste1), len(liste2))
3.- How could I use the generator to get the result?
A: For it to be a generator you need to yield the nedeed value:
def zipp2 (liste1,liste2):
i = 0
minval = min(len(liste1), len(liste2))
while i< minval:
yield (liste1[i], liste2[i])
i += 1
# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
print(p)
and get the results...
<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
trying to answer your questions...
1.- why?
A: As many have mention, you return the zipped
list as a list generators within the list comprehension [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
, not a nice way of doing by the way. that's why you get those generators.
2.- What do I need to change or where can I read/hear more to get "enlightened" myself?
A: If you still want to do that way, you only have to append the two items, by moving the parenthesis and removing the tuple function, like so:
def zipp (liste1, liste2):
length = len(liste1)
zipped =
[zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ] # not the best way, but still works. This created list is never used.
return zipped
then it's possible to return the list
zipp([1,2,3], ['a','b','c'])
Note that this asumes both list have same length. Otherwise you have to choose one (like you are doing) or finding the minimum of both lengths (it's also posible to choose the longest and fill with whatever it's needed):
min(len(liste1), len(liste2))
3.- How could I use the generator to get the result?
A: For it to be a generator you need to yield the nedeed value:
def zipp2 (liste1,liste2):
i = 0
minval = min(len(liste1), len(liste2))
while i< minval:
yield (liste1[i], liste2[i])
i += 1
# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
print(p)
and get the results...
<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
edited Nov 21 at 23:02
answered Nov 21 at 17:40
Traxidus Wolf
7510
7510
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
add a comment |
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
Thanks for the zipp2 snippet. But my question regarded my accidental generator generation. I thought there might be a way to get real values by using this accidental generator?
– Andreas K.
Nov 21 at 18:55
as @Jean-François Fabre's comment says: don't append it, extend it. like so:
zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
as @Jean-François Fabre's comment says: don't append it, extend it. like so:
zipped.extend( [(liste1[i], liste2[i]) for i in range(length)] )
– Traxidus Wolf
Nov 21 at 22:58
extend() method takes an interable as argument, so it also works without the square brackets:
zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
extend() method takes an interable as argument, so it also works without the square brackets:
zipped.extend( (liste1[i], liste2[i]) for i in range(length) )
– Traxidus Wolf
Nov 21 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 at 7:36
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53416993%2flist-comprehension-of-tuple-gets-me-a-generator-why-and-how-to-modify%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
This is abusing a side-effect of list comprehensions; this is not considered good practice. You're using the list comprehension to drive what should be a
for
loop.– roganjosh
Nov 21 at 16:54
You should definitely never use a list comprehension for side-effects. especially not in this case, were your list-comprehension should be doing the appending...
– juanpa.arrivillaga
Nov 21 at 16:55
1
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 at 16:57
1
List comprehensions can mutate mutable objects as though the list comprehension was a regular
for
loop. So, I could use a list comprehension like so;my_list = ; [my_list.append(x) for x in range(5)]
. In this instance, the list comprehension does not generate its own list at all. Instead, it modifies a different list altogether. This is considered a side effect; the correct approach would bemy_list = [x for x in range(5)]
.. Silly example, but hopefully illustrates the point.– roganjosh
Nov 21 at 18:59
1
Sorry for the multiple edits, on a phone. Obviously the best way in my example would just be
my_list = list(range(5))
but I'm shooting for an example with minimal fighting against autocorrect to illustrate my point– roganjosh
Nov 21 at 19:04