2

I have a list of dictionaries with 2 keys: 'name' & 'value'. I need to get the value of 'value' key if value of 'name' key is 'Subject'

Currently i'm iterating through each dict and checking the value of 'name' and getting the value of 'value'. Is there any improved way of doing this ?

items = [
            {
                "name": "From",
                "value": "from@example.com"
            },
            {
                "name": "Date",
                "value": "Tue, 8 Sep 2014 16:18:35 +0530"
            },
            {
                "name": "Subject",
                "value": "Test Subject"
            },
            {
                "name": "To",
                "value": "sender@example.com"
            },
        ]

for item in items:
    if item.get('name') == 'Subject':
        print "Subject: " + item.get('value')
Rookie
  • 429
  • 5
  • 16

3 Answers3

3

You should transpose your data into a dict instead:

>>> d = dict([(e['name'],e['value']) for e in items])    # transpose

Or a slightly easier way as mentioned by Peter Wood in the comments:

>>> d = {e['name']: e['value'] for e in items}

Then just use the dict as normal:

>>> d['Subject']
'Test Subject'
Tim
  • 41,901
  • 18
  • 127
  • 145
Jonas Byström
  • 25,316
  • 23
  • 100
  • 147
  • *You should transpose your data into a dict instead* - why? – Tim Sep 10 '15 at 08:25
  • 1
    @TimCastelijns Algorithms and data structures go hand in hand. OP has the wrong data structure for this sort of algorithm, so Jonas is temporarily creating the right data structure. Maybe the OP will think about replacing it permanently. – Peter Wood Sep 10 '15 at 08:40
  • 2
    @PeterWood sorry my comment wasn't really clear. *I* know why a dict is better, but maybe OP does not. Telling him why a dict is better instead of saying "just do it" would be better I think – Tim Sep 10 '15 at 08:43
  • 2
    `{e['name']: e['value'] for e in items}` – Peter Wood Sep 10 '15 at 08:43
  • 1
    I would use defaultdict, in case of more one dict with "name: Subject". – Ali SAID OMAR Sep 10 '15 at 08:45
  • @TimCastelijns I know you know (c: The comment addressed to you was for OP's benefit. – Peter Wood Sep 10 '15 at 08:45
  • To build on what @AliSAIDOMAR said, it's possible that this weird list-of-dictionaries was specifically an attempt to build a `dict`-like structure that can handle duplicate keys. I don't think it's a _good_ way --- a `dict` mapping each string to a `list` of values would be far easier to use --- but it strikes me as the sort of thing I'd have written back before I knew you could nest data structures like that. – Kevin J. Chase Sep 10 '15 at 08:59
  • @KevinJ.Chase: That occurred to me to, but can't catch 'em all. Without more info, this was the best I could do, and apparently it was correct in OP's particular case. One other thing that often goes through my head is that Python still strikes me as exceptionally concise, and every time I have a chance to manage some annoying datastructure with a one-liner I jump at it. That was how I learned and I hope author and other n00bs work approximately the same. – Jonas Byström Sep 16 '15 at 19:44
2

You could use next along with a generator filtering and converting the items.

>>> subject = next(field['value']
...                for field in items
...                if field['name'] == 'Subject')
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
1

As Jonas told, better for modify your structure because

from collections import defaultdict
it = [
            {
                "name": "From",
                "value": "from@example.com"
            },
            {
                "name": "Date",
                "value": "Tue, 8 Sep 2014 16:18:35 +0530"
            },
            {
                "name": "Subject",
                "value": "Test Subject"
            },
            {
                "name": "Subject",
                "value": "Test Subject 55"
            },
            {
                "name": "To",
                "value": "sender@example.com"
            },
        ]


result = defaultdict(list)
# shorcut better to use for...
[result[item["name"]].append(item["value"]) for item in it]

print(result["Subject"])
['Test Subject', 'Test Subject 55']
Community
  • 1
  • 1
Ali SAID OMAR
  • 6,404
  • 8
  • 39
  • 56