List comprehension of tuple gets me a generator - why and how to modify?
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
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 '18 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 '18 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 '18 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 '18 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 '18 at 19:04
|
show 11 more comments
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 '18 at 17:02
Andreas K.
asked Nov 21 '18 at 16:53
Andreas K.Andreas K.
121212
121212
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 '18 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 '18 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 '18 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 '18 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 '18 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 '18 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 '18 at 16:55
1
@roganjosh they are trying to re-implementzip
.
– juanpa.arrivillaga
Nov 21 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 16:55
1
1
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 '18 at 16:57
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 '18 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 '18 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 '18 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 '18 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 '18 at 19:04
|
show 11 more comments
2 Answers
2
active
oldest
votes
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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 at 19:29
add a comment |
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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 at 7:36
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 at 19:29
add a comment |
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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 at 19:29
add a comment |
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 '18 at 17:20
answered Nov 21 '18 at 17:05
Jean-François Fabre♦Jean-François Fabre
106k1057115
106k1057115
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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 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 '18 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 '18 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 '18 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 '18 at 19:00
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 at 19:29
don't append to a list with a list, extend it.
– Jean-François Fabre♦
Nov 21 '18 at 19:29
add a comment |
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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 at 7:36
add a comment |
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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 at 7:36
add a comment |
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 '18 at 23:02
answered Nov 21 '18 at 17:40
Traxidus WolfTraxidus Wolf
10011
10011
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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 23:14
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 at 7:36
Ok. Thanks. I didn't now this method yet.
– Andreas K.
Nov 22 '18 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.
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 '18 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 '18 at 16:55
1
@roganjosh they are trying to re-implement
zip
.– juanpa.arrivillaga
Nov 21 '18 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 '18 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 '18 at 19:04