lob0
lob0

Reputation: 317

Parse dict into specific list format using Python

Say I have the following dict

{'red':'boop','white':'beep','rose':'blip'}

And I want to get it to a list like so

['red','boop','end','white','beep','rose','blip','end']

The key / value which is to be placed in front of the list is an input.

So I essentially I want [first_key, first_value,end, .. rest of the k/v pairs..,end]

I wrote a brute force approach but I feel like there's a more pythonic way of doing it (and also because once implemented the snippet would make my code O(n^2) )

for item in lst_items    
    data_lst = []
    for key, value in item.iteritems():
        data_lst.append(key)
        ata_lst.append(value)
    #insert 'end' at the appropiate indeces
 #more code ...

Any pythonic approach?

Upvotes: 1

Views: 123

Answers (5)

Seyi Shoboyejo
Seyi Shoboyejo

Reputation: 529

data_lst = [x for k, v in lst_itemsL.iteritems() for x in (k, v) ] 
data_lst.insert(2, 'end') 
data_lst.append('end') 

This is pythonic; though will likely have the same efficiency (which can't be helped here). This should be faster than placing if blocks inside the loops...

Upvotes: 0

Zach
Zach

Reputation: 146

from itertools import chain
list(chain(*item.items())) + ['end']

Upvotes: 0

tobias_k
tobias_k

Reputation: 82899

You could use enumerate and check the current index:

>>> d = {'red':'boop','white':'beep','rose':'blip'}
>>> [x for i, e in enumerate(d.items())
...    for x in (e + ("end",) if i in (0, len(d)-1) else e)]
...
['white', 'beep', 'end', 'red', 'boop', 'rose', 'blip', 'end']

However, your original idea, first chaining the keys and values and then inserting the "end" items would not have O(n²), either. It would be O(n) followed by another O(n), hence still O(n).

Upvotes: 0

Patrick Haugh
Patrick Haugh

Reputation: 60984

The below relies on itertools.chain.from_iterable to flatten the items into a single list. We pull the first two values from the chain and then use them to build a new list, which we extend with the rest of the values.

from itertools import chain

def ends(d):
    if not d:
        return []
    c = chain.from_iterable(d.iteritems())
    l = [next(c), next(c), "end"]
    l.extend(c)
    l.append("end")
    return l

ends({'red':'boop','white':'beep','rose':'blip'})
# ['rose', 'blip', 'end', 'white', 'beep', 'red', 'boop', 'end']

If you know the key you want first, and don't care about the rest, we can use a lazily evaluated generator expression to remove it from the flattened list.

def ends(d, first):
    if not d:
        return []
    c = chain.from_iterable((k, v) for k, v in d.iteritems() if k != first)
    l = [first, d[first], "end"]
    l.extend(c)
    l.append("end")
    return l

ends({'red':'boop','white':'beep','rose':'blip'}, 'red')
# ['red', 'boop', 'end', 'rose', 'blip', 'white', 'beep', 'end']

Upvotes: 2

Andrej Kesely
Andrej Kesely

Reputation: 195438

The first key is specified in first variable:

first = 'red'

d = {'red':'boop','white':'beep','rose':'blip'}

new_l = [first, d[first], 'end']
for k, v in d.items():
    if k == first:
        continue
    new_l.append(k)
    new_l.append(v)
new_l.append('end')
print(new_l)

Prints:

['red', 'boop', 'end', 'white', 'beep', 'rose', 'blip', 'end']

Upvotes: 1

Related Questions