With given key-pair tuples, I need to create a dictionary - python

Using the key-pair tuples from my_file.txt, create a dictionary. If a key exists multiple times with different values, use the first seen value
(e.g., the first instance we encountered the key).
my_file = [('a', '1')
('b', '2')
('c', '3')
('d', '4')
('e', '5')]
def makehtml(fname):
with open(fname) as f: # reads lines from a fname file
for line in f:
tups = line2tup(line,"--") # turns each line into a 2 elem tuple on it's own line.
print tups
How can I create a dictionary from my_file key/value pairs. I've tried dict(my_file), but it's telling me that "ValueError: dictionary update sequence element #0 has length 1; 2 is required".

The dict constructor accepts a list of tuples as a parameter:
>>> my_file = [('a', '1'),
('b', '2'),
('c', '3'),
('d', '4'),
('e', '5')]
>>> dict(my_file)
{'e': '5', 'd': '4', 'c': '3', 'b': '2', 'a': '1'}
Edit: ahh, i got your problem. Assuming your file looks like this:
('a', '1')
('b', '2')
('c', '3')
('d', '4')
('e', '5')
Then this should work:
def makehtml(fname):
with open(fname) as f:
d = {}
for line in f:
key, value = line2tup(line,"--")
d[key] = value
return d

How about this:
mydict = {}
for line in open(fname):
k, v = line.split()
mydict[int(k)] = v

Related

Converting list in list to dictionary

I got a list like this:
[['a','b','1','2']['c','d','3','4']]
and I want to convert this list to dictionary something looks like this:
{
('a','b'):('1','2'),
('c','d'):('3','4')
}
for example, ('a', 'b') & ('c','d') for key
and ('1','2') &('3','4') for value
so I used code something like this
new_dict = {}
for i, k in enumerate(li[0:2]):
new_dict[k] =[x1[i] for x1 in li[2:]]
print(new_dict)
,but it caused unhashable type error 'list'
I tried several other way, but it didn't work well..
Is there any way that I can fix it?
You can't have list as key, but tuple is possible. Also you don't need to slice on your list, but on the sublist.
You need the 2 first values sublist[:2] as key and the corresponding values is the sublist from index 2 sublist[2:]
new_dict = {}
for sublist in li:
new_dict[tuple(sublist[:2])] = tuple(sublist[2:])
print(new_dict) # {('a', 'b'): ('1', '2'), ('c', 'd'): ('3', '4')}
The same with dict comprehension
new_dict = {tuple(sublist[:2]): tuple(sublist[2:]) for sublist in li}
print(new_dict) # {('a', 'b'): ('1', '2'), ('c', 'd'): ('3', '4')}
li = [['a','b','1','2'],['c','d','3','4']]
new_dict = {}
for item in li:
new_dict[(item[0], item[1])] = (item[2], item[3])
I would use list-comprehension following way:
lst = [['a','b','1','2']['c','d','3','4']]
dct = dict([(tuple(i[:2]),tuple(i[2:])) for i in lst])
print(dct)
or alternatively dict-comprehension:
dct = {tuple(i[:2]):tuple(i[2:]) for i in lst}
Output:
{('a', 'b'): ('1', '2'), ('c', 'd'): ('3', '4')}
Note that list slicing produce lists, which are mutable and can not be used as dict keys, so I use tuple to convert these to immutable tuples.
You can do it with dict comprehension:
li = [
['a', 'b', '1', '2'],
['c', 'd', '3', '4'],
]
new_dict = {(i[0], i[1]): (i[2], i[3]) for i in li}
print(new_dict)
# result
{('a', 'b'): ('1', '2'), ('c', 'd'): ('3', '4')}

two list integer combine together in python

I am trying to get integers value from a list of specific functions in a two different list and then try to store both list integer with combination of 2nd list integer.
let suppose we have two list,
list1 = ['A(0)','B(1)','C(3)','Z(4)','Z(7)','Z(2)', 'X(3)','X(2)',...]
list2 = ['A(0)','B(1)','C(3)','Z(7)','Z(3)','Z(5)', 'X(11)','X(4)',...]
now only the integer of Z from list1 and list2 will extract and store like this sequence,
Z1 = A(4,7)
Z1 = A(7,3)
Z2 = B(2,5)
first element of list1 and 2nd element of list2 in a sequence.
here is my code which i tried,
for line in list1:
if 'OUTPUT' in line:
print(line.split('Z(')[1].split(')')[0].strip())
for line in list2:
if 'OUTPUT' in line:
print(line.split('Z(')[1].split(')')[0].strip())
here is output
4 7 7 3 2 5
but still i didnt get value like,
Z1 = A(4,7)
Z1 = A(7,3)
Z2 = B(2,5)
def format_list(lst):
new = []
for sub in lst:
open_p = sub.index("(")
close_p = sub.index(")")
letter = sub[:open_p]
number = sub[open_p + 1 : close_p]
new.append((letter, number))
return new
list1 = ["A(0)", "B(1)", "C(3)", "Z(4)", "Z(7)", "Z(2)", "X(3)", "X(2)"]
list2 = ["A(0)", "B(1)", "C(3)", "Z(7)", "Z(3)", "Z(5)", "X(11)", "X(4)"]
lst1 = format_list(list1)
lst2 = format_list(list2)
The above code will format the lists as so:
lst1 = [('A', '0'), ('B', '1'), ('C', '3'), ('Z', '4'), ('Z', '7'), ('Z', '2'), ('X', '3'), ('X', '2')]
lst2 = [('A', '0'), ('B', '1'), ('C', '3'), ('Z', '7'), ('Z', '3'), ('Z', '5'), ('X', '11'), ('X', '4')]
From there, you'll be able to use filter() to find the places in which the numbers differentiate:
different_obj = list(filter(lambda x: x[0][1] != x[1][1], zip(lst1, lst2)))
print(different_obj)
Or if you rather, you don't need to use filter:
different_obj = []
for x, y in zip(lst1, lst2):
if x[1] != y[1]:
different_obj.append((x, y))
outputs:
[(('Z', '4'), ('Z', '7')),
(('Z', '7'), ('Z', '3')),
(('Z', '2'), ('Z', '5')),
(('X', '3'), ('X', '11')),
(('X', '2'), ('X', '4'))]
From there you should be able to organize different_obj to your goal.

Iterating over a Python 2D list to find the value

I am trying to iterate over a Python 2D list. As the algorithm iterates over the list, it will add the key to a new list until a new value is detected. An operation is then applied to the list and then the list is emptied so that it can be used again as follows:
original_list = [('4', 'a'), ('3', 'a'), ('2', 'a'), ('1', 'b'), ('6', 'b')]
When the original_list is read by the algorithm it should evaluate the second value of each object and decipher if it is different from the previous value; if not, add it to a temporary list.
Here is the psedo code
temp_list = []
new_value = original_list[0][1] #find the first value
for key, value in original_list:
if value != new_value:
temp_list.append(new_value)
Should output
temp_list = ['4', '3', '2']
temp_list = []
prev_value = original_list[0][1]
for key, value in original_list:
if value == prev_value:
temp_list.append(key)
else:
do_something(temp_list)
print temp_list
temp_list = [key]
prev_value = value
do_something(temp_list)
print temp_list
# prints ['4', '3', '2']
# prints ['1', '6']
Not entirely sure what you are asking, but I think itertools.groupby could help:
>>> from itertools import groupby
>>> original_list = [('4', 'a'), ('3', 'a'), ('2', 'a'), ('1', 'b'), ('6', 'b')]
>>> [(zip(*group)[0], k) for k, group in groupby(original_list, key=lambda x: x[1])]
[(('4', '3', '2'), 'a'), (('1', '6'), 'b')]
What this does: It groups the items in the list by their value with key=lambda x: x[1] and gets tuples of keys corresponding to one value with (zip(*group)[0], k).
In case your "keys" do not repeat themselves, you could just use a defaultdict to "sort" the values based on keys, then extract what you need
from collections import defaultdict
ddict = defaultdict(list)
for v1, v2 in original_list:
ddict[v2].append(v1)
ddict values are now all temp_list:
>>> ddict["a"]
['4', '3', '2']

Python dictionary key assign

I've created a dictionary from a tuple, but can't seem to find an answer as to how I'd switch my keys and values without editing the original tuple. This is what I have so far:
tuples = [('a', '1'), ('b', '1'), ('c', '2'), ('d', '3')]
dic = dict(tuples)
print dic
This gives the output:
{'a': '1', 'b': ''1', 'c': '2', 'd': '3'}
But I'm looking for:
{'1': 'a' 'b', '2': 'c', '3': 'd'}
Is there a simple code that could produce this?
Build a dictionary in a loop, collecting your values into lists:
result = {}
for value, key in tuples:
result.setdefault(key, []).append(value)
The dict.setdefault() method will set and return a default value if the key isn't present. Here I used it to set a default empty list value if the key is not present, so the .append(value) is applied to a list object, always.
Don't try to make this a mix of single string and multi-string list values, you'll only complicate matters down the road.
Demo:
>>> tuples = [('a', '1'), ('b', '1'), ('c', '2'), ('d', '3')]
>>> result = {}
>>> for value, key in tuples:
... result.setdefault(key, []).append(value)
...
>>> result
{'1': ['a', 'b'], '3': ['d'], '2': ['c']}
from operator import itemgetter
from itertools import groupby
first = itemgetter(0)
second = itemgetter(1)
d = dict((x, [v for _, v in y]) for x, y in groupby(sorted(tuples, key=second), key=second)
groupby groups the tuples into a new iterator of tuples, whose first element is the unique second item of each of the original, and whose second element is another iterator consisting of the corresponding first items. A quick example (pretty-printed for clarity):
>>> list(groupby(sorted(tuples, key=second), key=second)))
[('1', <itertools._grouper object at 0x10910b8d0>),
('2', <itertools._grouper object at 0x10910b790>),
('3', <itertools._grouper object at 0x10910b750>)]
The sorting by the same key used by groupby is necessary to ensure all like items are grouped together; groupby only makes one pass through the list.
The subiterators consist of tuples like ('1', 'a'), so the second value in each item is the one we want to add to the value in our new dictionary.

Loop through dictionary with a math function

I have this dictionary in which in which (key1, key2): value
dict = {('1', '4'): 'A', ('3', '8'): 'B', ('4', '7'): 'C',
('8', '9'): 'D', ('4', '2'): 'E', ('2', '0'): 'F', ('3', '9'):
'G', ('7', '7'): 'H', ('8', '6'): 'I', ('5', '3'): 'J',
('6', '1'): 'K'}
key1 = input('enter value of key1: ')
key2 = input('enter value of key2: ')
If I input a pair of key1, key2 and the pair doesn't exist, is there any way that I can loop through this dictionary and pass a math function i.e. to find average value for each pair of keys and print the one that has the biggest average value?
Edit: Actually this dictionary was derived from a text file, so it has to be in string first and I need to convert it to int but I don't know how.
Don't call it dict, that prevents you from accessing the built-in dict.
Your keys are strings, so there is no average value. If we convert to ints:
dct = dict((tuple(map(int, key)), value) for key, value in str_dict.iteritems())
Which gives:
dct = {(8, 9): 'D', (4, 7): 'C', (6, 1): 'K', (7, 7): 'H',
(1, 4): 'A', (3, 8): 'B', (2, 0): 'F', (3, 9): 'G',
(4, 2): 'E', (8, 6): 'I', (5, 3): 'J'}
Then you can use max on the sum of each key:
key = max(d, key=sum)
# (8, 9) is the key with the highest average value
Since the one with the highest sum also has the highest average.
If you then want the value for that key, it's:
value = dct[key]
# 'D' is the value for (8, 9)
# Use NumPy. It seems this will help if you'll be needing argmin type functions.
# This is BY NO MEANS the only way to do it in Python, but it is a good way to
# know nonetheless.
import numpy as np
my_dict = {('1', '4'): 'A', ('3', '8'): 'B', ('4', '7'): 'C',
('8', '9'): 'D', ('4', '2'): 'E', ('2', '0'): 'F', ('3', '9'):
'G', ('7', '7'): 'H', ('8', '6'): 'I', ('5', '3'): 'J',
('6', '1'): 'K'}
# Get the keys
dict_keys = my_dict.keys()
# Get the average value of each key pair.
averages_for_keys = np.array([np.mean(elem) for elem in dict_keys])
# Get the index and the key pair of the largest average.
largest_average_key = dict_keys[averages_for_keys.argmax()]
# Get user input
key1 = input('enter value of key1: ')
key2 = input('enter value of key2: ')
# If not in dict_keys, print for largest average key pair.
if (key1, key2) not in dict_keys:
print "Invalid input key pair. Proceeding with largest average."
print my_dict[largest_average_key]
###
# An alternative to index on the closest key by Euclidean distance.
# This can be adjusted for other distances as well.
###
if (key1, key2) not in dict_keys:
print "Didn't find key pair in dict."
print "Proceeding with keypair of minimal distance to input."
dists = np.array([sqrt((elem[0]-key1)**2.0 + (elem[1]-key2)**2.0) for elem in dict_keys])
min_index = dists.argmin()
closest_key = dict_keys[min_index]
print my_dict[closest_key]

Categories

Resources