Extracting elements from two lists of dicts if other elements match using comprehension
How can I iterate over two lists of dicts, match dicts between the lists by a key, and if there is a match then append a specific key from each dict into a key value pair in a new dictionary. Let me clarify with an example:
l1 = [{'id': 52, 'email': 'someemail@yahoo.com', 'anotherfield': 'some value'},
.....
{'id': 98, 'email': 'anotheremail@yahoo.com', 'anotherfield': 'another value'}]
l2 = [{'id': 93, 'email': 'someemail@yahoo.com', 'another key': 'seventeen'},
.....
{'id': 101, 'email': 'anotheremail@yahoo.com', 'another key': 'twenty'}]
# match the 'email' keys between each list, and if match, create k, v pair from id's
desired_output = {'52': 93.....'98': 101}
I can achieve this quite easily by simply iterating over each list as follows:
lookup = dict()
for l in l1:
for p in l2:
if l['email']==p['email']:
lookup[l['id']]=p['id']
break
However this is a bit clunky and I'd prefer some kind of comprehension. My attempt:
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
python dictionary list-comprehension
|
show 2 more comments
How can I iterate over two lists of dicts, match dicts between the lists by a key, and if there is a match then append a specific key from each dict into a key value pair in a new dictionary. Let me clarify with an example:
l1 = [{'id': 52, 'email': 'someemail@yahoo.com', 'anotherfield': 'some value'},
.....
{'id': 98, 'email': 'anotheremail@yahoo.com', 'anotherfield': 'another value'}]
l2 = [{'id': 93, 'email': 'someemail@yahoo.com', 'another key': 'seventeen'},
.....
{'id': 101, 'email': 'anotheremail@yahoo.com', 'another key': 'twenty'}]
# match the 'email' keys between each list, and if match, create k, v pair from id's
desired_output = {'52': 93.....'98': 101}
I can achieve this quite easily by simply iterating over each list as follows:
lookup = dict()
for l in l1:
for p in l2:
if l['email']==p['email']:
lookup[l['id']]=p['id']
break
However this is a bit clunky and I'd prefer some kind of comprehension. My attempt:
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
python dictionary list-comprehension
1
Your for-loop is fine. But if you are going to use a comprehension, you'd need{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.
– juanpa.arrivillaga
Nov 21 '18 at 14:03
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
1
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
1
The order of elements in lists is consistency? If not, algorithm is not working.if k['email'] == v['email']
will works thenk[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists:d = defaultdict(list)
,d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12
|
show 2 more comments
How can I iterate over two lists of dicts, match dicts between the lists by a key, and if there is a match then append a specific key from each dict into a key value pair in a new dictionary. Let me clarify with an example:
l1 = [{'id': 52, 'email': 'someemail@yahoo.com', 'anotherfield': 'some value'},
.....
{'id': 98, 'email': 'anotheremail@yahoo.com', 'anotherfield': 'another value'}]
l2 = [{'id': 93, 'email': 'someemail@yahoo.com', 'another key': 'seventeen'},
.....
{'id': 101, 'email': 'anotheremail@yahoo.com', 'another key': 'twenty'}]
# match the 'email' keys between each list, and if match, create k, v pair from id's
desired_output = {'52': 93.....'98': 101}
I can achieve this quite easily by simply iterating over each list as follows:
lookup = dict()
for l in l1:
for p in l2:
if l['email']==p['email']:
lookup[l['id']]=p['id']
break
However this is a bit clunky and I'd prefer some kind of comprehension. My attempt:
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
python dictionary list-comprehension
How can I iterate over two lists of dicts, match dicts between the lists by a key, and if there is a match then append a specific key from each dict into a key value pair in a new dictionary. Let me clarify with an example:
l1 = [{'id': 52, 'email': 'someemail@yahoo.com', 'anotherfield': 'some value'},
.....
{'id': 98, 'email': 'anotheremail@yahoo.com', 'anotherfield': 'another value'}]
l2 = [{'id': 93, 'email': 'someemail@yahoo.com', 'another key': 'seventeen'},
.....
{'id': 101, 'email': 'anotheremail@yahoo.com', 'another key': 'twenty'}]
# match the 'email' keys between each list, and if match, create k, v pair from id's
desired_output = {'52': 93.....'98': 101}
I can achieve this quite easily by simply iterating over each list as follows:
lookup = dict()
for l in l1:
for p in l2:
if l['email']==p['email']:
lookup[l['id']]=p['id']
break
However this is a bit clunky and I'd prefer some kind of comprehension. My attempt:
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
python dictionary list-comprehension
python dictionary list-comprehension
edited Nov 21 '18 at 13:59
asked Nov 21 '18 at 13:52
Laurie Bamber
431114
431114
1
Your for-loop is fine. But if you are going to use a comprehension, you'd need{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.
– juanpa.arrivillaga
Nov 21 '18 at 14:03
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
1
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
1
The order of elements in lists is consistency? If not, algorithm is not working.if k['email'] == v['email']
will works thenk[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists:d = defaultdict(list)
,d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12
|
show 2 more comments
1
Your for-loop is fine. But if you are going to use a comprehension, you'd need{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.
– juanpa.arrivillaga
Nov 21 '18 at 14:03
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
1
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
1
The order of elements in lists is consistency? If not, algorithm is not working.if k['email'] == v['email']
will works thenk[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists:d = defaultdict(list)
,d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12
1
1
Your for-loop is fine. But if you are going to use a comprehension, you'd need
{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.– juanpa.arrivillaga
Nov 21 '18 at 14:03
Your for-loop is fine. But if you are going to use a comprehension, you'd need
{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.– juanpa.arrivillaga
Nov 21 '18 at 14:03
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
1
1
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
1
1
The order of elements in lists is consistency? If not, algorithm is not working.
if k['email'] == v['email']
will works then k[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists: d = defaultdict(list)
, d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12
The order of elements in lists is consistency? If not, algorithm is not working.
if k['email'] == v['email']
will works then k[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists: d = defaultdict(list)
, d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12
|
show 2 more comments
2 Answers
2
active
oldest
votes
Try this:
from itertools import product
lookup = {k['id']: v['id'] for k, v in product(l1, l2) if k['email'] == v['email']}
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
add a comment |
Solution for unconsistency lists:
l1 = [{"email": "email1", "id": 1}, {"email": "email2", "id": 2}, {"email": "email3", "id": 3}]
l2 = [{"email": "email2", "id": 22}, {"email": "email4", "id": 4}, {"email": "email1", "id": 11}, ]
emails = {}
lookup = {}
for el in l1:
emails[el["email"]] = el["id"]
for el in l2:
email = el["email"]
if email in emails:
lookup[emails[email]] = el["id"]
# {1: 11, 2: 22}
print(lookup)
# bad solution from question
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
# {} - empty
print(lookup)
If you need more lists - extend solution, update emails dictionary on all loops before finally loop
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%2f53413594%2fextracting-elements-from-two-lists-of-dicts-if-other-elements-match-using-compre%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
Try this:
from itertools import product
lookup = {k['id']: v['id'] for k, v in product(l1, l2) if k['email'] == v['email']}
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
add a comment |
Try this:
from itertools import product
lookup = {k['id']: v['id'] for k, v in product(l1, l2) if k['email'] == v['email']}
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
add a comment |
Try this:
from itertools import product
lookup = {k['id']: v['id'] for k, v in product(l1, l2) if k['email'] == v['email']}
Try this:
from itertools import product
lookup = {k['id']: v['id'] for k, v in product(l1, l2) if k['email'] == v['email']}
answered Nov 21 '18 at 13:56
mehrdad-pedramfar
4,66711236
4,66711236
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
add a comment |
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
This is definitely working so thanks for that. Is there any solution which wouldn't involve importing an additional module?
– Laurie Bamber
Nov 21 '18 at 14:04
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
importing itertools does not have a lot of costs. but to answer to your question is should say yes. but you should implement product your self(to match all of items from both list together)
– mehrdad-pedramfar
Nov 21 '18 at 14:15
add a comment |
Solution for unconsistency lists:
l1 = [{"email": "email1", "id": 1}, {"email": "email2", "id": 2}, {"email": "email3", "id": 3}]
l2 = [{"email": "email2", "id": 22}, {"email": "email4", "id": 4}, {"email": "email1", "id": 11}, ]
emails = {}
lookup = {}
for el in l1:
emails[el["email"]] = el["id"]
for el in l2:
email = el["email"]
if email in emails:
lookup[emails[email]] = el["id"]
# {1: 11, 2: 22}
print(lookup)
# bad solution from question
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
# {} - empty
print(lookup)
If you need more lists - extend solution, update emails dictionary on all loops before finally loop
add a comment |
Solution for unconsistency lists:
l1 = [{"email": "email1", "id": 1}, {"email": "email2", "id": 2}, {"email": "email3", "id": 3}]
l2 = [{"email": "email2", "id": 22}, {"email": "email4", "id": 4}, {"email": "email1", "id": 11}, ]
emails = {}
lookup = {}
for el in l1:
emails[el["email"]] = el["id"]
for el in l2:
email = el["email"]
if email in emails:
lookup[emails[email]] = el["id"]
# {1: 11, 2: 22}
print(lookup)
# bad solution from question
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
# {} - empty
print(lookup)
If you need more lists - extend solution, update emails dictionary on all loops before finally loop
add a comment |
Solution for unconsistency lists:
l1 = [{"email": "email1", "id": 1}, {"email": "email2", "id": 2}, {"email": "email3", "id": 3}]
l2 = [{"email": "email2", "id": 22}, {"email": "email4", "id": 4}, {"email": "email1", "id": 11}, ]
emails = {}
lookup = {}
for el in l1:
emails[el["email"]] = el["id"]
for el in l2:
email = el["email"]
if email in emails:
lookup[emails[email]] = el["id"]
# {1: 11, 2: 22}
print(lookup)
# bad solution from question
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
# {} - empty
print(lookup)
If you need more lists - extend solution, update emails dictionary on all loops before finally loop
Solution for unconsistency lists:
l1 = [{"email": "email1", "id": 1}, {"email": "email2", "id": 2}, {"email": "email3", "id": 3}]
l2 = [{"email": "email2", "id": 22}, {"email": "email4", "id": 4}, {"email": "email1", "id": 11}, ]
emails = {}
lookup = {}
for el in l1:
emails[el["email"]] = el["id"]
for el in l2:
email = el["email"]
if email in emails:
lookup[emails[email]] = el["id"]
# {1: 11, 2: 22}
print(lookup)
# bad solution from question
lookup = {k['id']: v['id'] for k, v in zip(l1, l2) if k['email'] == v['email']}
# {} - empty
print(lookup)
If you need more lists - extend solution, update emails dictionary on all loops before finally loop
answered Nov 21 '18 at 14:39
Maxim Panfilov
150111
150111
add a comment |
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%2f53413594%2fextracting-elements-from-two-lists-of-dicts-if-other-elements-match-using-compre%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
1
Your for-loop is fine. But if you are going to use a comprehension, you'd need
{... for l in l1 for p in l2 if l['email']==p['email']}
note how it aligns with your for-loop. However, you won't be able to break, making this less ideal. In any event, there are better algorithms than a brute-force check, so, I'd rather change that than convert from a perfectly fine for-loop to comprehension.– juanpa.arrivillaga
Nov 21 '18 at 14:03
Interesting, could you provide the full line with your suggested edit?
– Laurie Bamber
Nov 21 '18 at 14:04
1
{l['id']:p['id'] for l in l1 for p in l2 if l['email']==p['email']}
– juanpa.arrivillaga
Nov 21 '18 at 14:05
This worked really nicely, thanks for the help, and I'll take a look into other methods that might be more robust. Thanks again.
– Laurie Bamber
Nov 21 '18 at 14:09
1
The order of elements in lists is consistency? If not, algorithm is not working.
if k['email'] == v['email']
will works thenk[N] == v[N]
. You need consist of lists and when run your solution. Or, you can create one dict from your lists:d = defaultdict(list)
,d[email].append(id)
– Maxim Panfilov
Nov 21 '18 at 14:12