Reputation: 1357
I have a list of tuples that look like this:
[('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),('name','Home Team'),('name','Away Team'),('name','Score'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January'),...]
Essentially what this is is a bunch of tables. For example, the first table would have the headers 'Name', 'Age', and 'Hometown' and the entry would be 'Bob', 27, 'Chicago'.
I am trying to turn this into one dictionary like this: {'Name':'Bob','Age':27,'Hometown':'Chicago, 'Home Team':'Broncos',...}
I believe I can do this in a normal case, however if you look at the second "table" there are 3 headers and only 2 values. Is there a way to map the first two 'names' in that case to the first two 'values' and map the third ('Score'
) to an empty string?
Upvotes: 0
Views: 114
Reputation: 11893
I think this works. May not be real pretty, but it should be rugged if you have several segments with missing values, and does not require altering the original list... Although I just learned zip_longest
. Thanks @Zunayn
A little while loop construct can chew through this:
data = [('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),
('name','Home Team'),('name','Away Team'),('name','Score'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January')]
# reverse the data for more efficient pop()
data = data[::-1]
results = {}
d = data.pop()
while data:
keys = []
while d[0] == 'name':
keys.append(d[1])
d = data.pop()
values = []
while d[0] == 'value':
values.append(d[1])
if data: # need to watch for end of list
d = data.pop()
else:
break
missing = len(keys) - len(values)
values.extend(['na']*missing)
# zip intermediate results and add to result
results.update({k:v for (k, v) in zip(keys, values)})
print(results)
Yields:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Score': 'na', 'Month': 'January'}
Upvotes: 1
Reputation: 132
Here is a solution I propose:
from itertools import zip_longest
tup = [('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),('name','Home Team'),('name','Away Team'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January'), ('name','Score')]
names = [item[1] for item in tup if item[0] == "name"]
values = [item[1] for item in tup if item[0] == "value"]
d = dict(zip_longest(names, values, fill_value=""))
Output:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Month': 'January', 'Score': ''}
You could use the standard zip()
function but as you said, you need to map the surplus keys to an empty string. For that purpose, use itertools.zip_longest
. And, remember that order is everything while zipping two iterables. In your question, the tuple ("name", "Score")
comes before ("name", "Month")
, and the last "value" is ("value", "January")
. This would map "Score" to January and not "Month". So, I changed the order in my example.
Hope this helped :)
Upvotes: 1
Reputation: 539
ol = [('name', 'Name'),
('name','Age'),
('name','Hometown'),
('value','Bob'),
('value',27),
('value','Chicago'),
('name','Home Team'),
('name','Away Team'),
('name','Score'),
('value','Broncos'),
('value','Patriots'),
('name','Month'),
('value','January')]
l = ol.copy()
d = {}
noValue = False
while len(l) > 0 :
i = 1
while l[i][0] != 'value':
i += 1
d[l[0][1]] = l[i][1]
if i == 2 and l[i+1][0] == 'name':
d[l[1][1]] = ''
l = l[i + 1:]
else:
l = l[1:i] + l[i + 1:]
print(d)
Printing:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Score': '', 'Month': 'January'}
This should work as long as only the last value is missing.
This list will not work [('name','Home Team'), ('name','Away Team'), ('name','Score'), ('value','Broncos'), ('name','Month'), ('value','January')]
Upvotes: 1
Reputation: 499
I just suggest, maybe do something like this. Of cource it will work if you names and values are stored in order.
Upvotes: 0