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]
Related
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')}
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.
I have two lists that defines a card
values = ['A', 'K', 'Q', 'J', '10', '9', '8', '7', '6', '5', '4', '3', '2']
marks = ['spade', 'hearts', 'diamond', 'club']
I want to have 12 unique cards, so my output should look like
('9', 'diamond')
('K', 'hearts')
('Q', 'hearts')
('7', 'spade')
('A', 'diamond')
('3', 'diamond')
('Q', 'diamond')
('3', 'hearts')
('7', 'hearts')
('2', 'diamond')
('2', 'hearts')
('5', 'spade')
I have used random choice to get this far, my code is here
count = 0
while count != 12:
value = random.choice(values)
mark = random.choice(marks)
card = Card(value, mark)
# I have a class named Card, generate() returns a tuple of mark and value for card
print(card.generate())
count += 1
But it does not provide me unique values. Please let me know or through me a resource to learn how to get unique value by random choice from two lists.
First, combine the marks and values to actual cards using itertools.product, then just random.shuffle the stack of cards and pop cards into the player's hand, like you would in real life.
import itertools, random
cards = list(itertools.product(values, marks))
random.shuffle(cards)
hand = [cards.pop() for _ in range(12)]
At the same time, this will remove the cards from the stack, and thus ensure that cards are unique across the different players' hands. If you do not want this, use random.sample instead. This way, cards are unique within one hand, but not across hands, as they remain in the stack (in this case, the shuffle step is not needed, either):
hand = random.sample(cards, 12)
What i would recommend is using random.sample(population, k) this will return a unique k items from the list population.
However for this you first need to make all the cards and then have all the cards in the list population.
Another solution would be to add a list chosen_cards and implement an equals funcion and do a check in the chosen_cards before you add the new random card to the chosen_cards.
You can do:
cards = [(v, m) for (v, m) in zip(values * 4, marks * 13)]
random.sample(cards, 12)
# RESULT
[('K', 'diamond'),
('K', 'spade'),
('3', 'spade'),
('6', 'hearts'),
('10', 'spade'),
('9', 'hearts'),
('3', 'club'),
('8', 'hearts'),
('Q', 'spade'),
('Q', 'hearts'),
('6', 'club'),
('J', 'diamond')]
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']
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