Function to return values in dictionary - python

This is my dictionary:
seven_segment = {'0': {'a','c','d','e','b','f'},
'1': {'c','b'},
'2': {'a','d','e','b','g'},
'3': {'a','c','d','b','g'},
'4': {'g','c','f','b'},
'5': {'a','c','d','g','f'},
'6': {'a','c','d','e','g','f'},
'7': {'a','c','b'},
'8': {'a','c','d','e','b','g','f'},
'9': {'a','c','d','b','g','f'}}
I have a function created:
def guess_damaged(display, state, damaged):
sorted_state = ''.join(sorted(state))
sorted_damaged = ''.join(sorted(damaged))
for key in display:
templist = list(display[key])
templist = sorted(templist)
templist = ''.join(templist)
if(templist == sorted_state):
return {key for key,value in display.items() if all(sorted_damaged in value for sorted_damaged in sorted_state)}
print(guess_damaged(seven_segment, 'adeg', 'bf'))
print(guess_damaged(seven_segment, 'abed', 'cf'))
print(guess_damaged(seven_segment, '', 'abcdefg'))
My current output is shown below:
None
None
None
However, this is my desired output:
{'2'}
{'0'}
{'4', '5', '1', '8', '7', '6', '3', '0', '2', '9'}
How can I get the desired output?

Solution
I think this is what you want:
seven_segment = {'0': {'a', 'c', 'd', 'e', 'b', 'f'},
'1': {'c', 'b'},
'2': {'a', 'd', 'e', 'b', 'g'},
'3': {'a', 'c', 'd', 'b', 'g'},
'4': {'g', 'c', 'f', 'b'},
'5': {'a', 'c', 'd', 'g', 'f'},
'6': {'a', 'c', 'd', 'e', 'g', 'f'},
'7': {'a', 'c', 'b'},
'8': {'a', 'c', 'd', 'e', 'b', 'g', 'f'},
'9': {'a', 'c', 'd', 'b', 'g', 'f'}}
def guess_damaged(display, state, damaged):
return {
key
for key, value in display.items()
if set(state) == (value - set(damaged))
}
print(guess_damaged(seven_segment, 'adeg', 'bf'))
print(guess_damaged(seven_segment, 'abed', 'cf'))
print(guess_damaged(seven_segment, '', 'abcdefg'))
output:
{'2'}
{'0'}
{'7', '1', '5', '0', '9', '4', '2', '6', '3', '8'}
Explaination
set is very powerful built-in class. reference page about set
You can perform with set:
union(|)
intersect(&)
difference(-)
symmetric difference(^)
subset relations(<=, <, >, >=)
equality(==, !=)

There is no value in the seven_segment dictionary that equals 'adeg' or 'abed' or '' when sorted, so the line with "if (templist == sorted_state):" never is true

Related

How to insert index, values of list into a dictionary values(based on length of the other list)?

I have two lists(l,s). Now I want to create a dictionary where I want to add the index values, values of the lists to a dictionary keys that looks like below.
{"value_s": index value of s, "Name_s": value of list s,'value_l': index value of l, 'value_s': value of list s}
Suppose list l have four values and s have two values, then based on the length of list l the number of index's should be added to s. If the length of l is 4 then the for loop should add one to four to value_s and the value_l should be 0 for the first run. This might be confusing for better understanding refer to the code and the excepted output below:-
l = ['a','b','c','d']
s = ['q','w']
The above are the two lists. Now the excepted output is:-
[{'value_s': '0', 'Name_s': 'q', 'value_l': 0, 'Name_l': 'a'},
{'value_s': '0', 'Name_s': 'q', 'value_l': 1, 'Name_l': 'b'},
{'value_s': '0', 'Name_s': 'q', 'value_l': 2, 'Name_l': 'c'},
{'value_s': '0', 'Name_s': 'q', 'value_l': 3, 'Name_l': 'd'},
{'value_s': '1', 'Name_s': 'w', 'value_l': 0, 'Name_l': 'a'},
{'value_s': '1', 'Name_s': 'w', 'value_l': 1, 'Name_l': 'b'},
{'value_s': '1', 'Name_s': 'w', 'value_l': 2, 'Name_l': 'c'},
{'value_s': '1', 'Name_s': 'w', 'value_l': 3, 'Name_l': 'd'},
]
All though I tried implementing the basic part of inserting the index and values. The idea what I did is not a good way to do
f=[]
for idx, val in enumerate(s):
for index, value in enumerate(l):
name = {"value_s":idx, "Name_s": val,'value_l':index, 'value_s':value }
f.append(name)
This gives me:-
[{'value_s': 'a', 'Name_s': 'q', 'value_l': 0},
{'value_s': 'b', 'Name_s': 'q', 'value_l': 1},
{'value_s': 'c', 'Name_s': 'q', 'value_l': 2},
{'value_s': 'd', 'Name_s': 'q', 'value_l': 3},
{'value_s': 'a', 'Name_s': 'w', 'value_l': 0},
{'value_s': 'b', 'Name_s': 'w', 'value_l': 1},
{'value_s': 'c', 'Name_s': 'w', 'value_l': 2},
{'value_s': 'd', 'Name_s': 'w', 'value_l': 3}]
Is there any good way to achieve the excepted output?
l = ['a','b','c','d']
s = ['q','w']
f=[]
for idx, val in enumerate(l):
for index, value in enumerate(s):
name = { "value_s":index, "Name_s": value, 'value_l':idx, 'name_l':val }
f.append(name)
print(f)

Access next element in a for loop in python

I have a list of lists, let's call it foo
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
and another list bar
bar = ['A', 'C', 'D', 'F', 'H']
I wanted search the elements of bar in foo and if they are find then the next element is to be picked and create a dictionary with keys as elements of bar.
What I tried:
pay = {}
for i in bar:
for j in foo:
for k in j:
if i == k:
try:
pay[i] = k+1
except:
pay[i] = '-'
Expected Output:
pay = {'A':1,
'C':5,
'D':9,
'F':'-',
'H':'-'}
You've missed,
Accessing the proper index to find the next element.
Using == operator instead of in property to check the value's presence in the list.
Solution:
bar = ['A', 'C', 'D', 'F', 'H']
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
output_dict = {}
for element in foo:
for foo_element in element:
if foo_element in bar:
try:
output_dict[foo_element] = element[element.index(foo_element) + 1]
except:
output_dict[foo_element] = '-'
print(output_dict)
Output:
{'D': '9', 'H': '-', 'F': '-', 'C': '5', 'A': '1'}
I would normalize the data, i.e. flatten the foo and convert it to a dict of all pairs {item: next_item}.
Then just get the data from this dict.
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']
pdict = {k:v for s in foo for k, v in zip(s, s[1:])}
# print(pdict) # uncomment to check
pay = {k: pdict.get(k, '-') for k in bar}
print(pay) # {'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}
As #kuro mentioned, you can use enumerate function or else you can simply iterate over the the indices as below.
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']
pay = {}
for i in bar:
for j in foo:
for k in range(len(j)):
if i == j[k]:
try:
pay[i] = j[k + 1]
except IndexError:
pay[i] = '-'
print(pay)
Output:
{'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}
list_of_lists = foo
flattened = [val for sublist in list_of_lists for val in sublist] + ['-']
pay = {}
for bar_val in bar:
pos = flattened.index(bar_val)
try:
pay[bar_val] = int(flattened[pos+1])
except ValueError as e:
pay[bar_val] = '-'
print(pay)
Output:
{'A': 1, 'C': 5, 'D': 9, 'F': '-', 'H': '-'}
You can try to do it this way as well:
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']
pay = dict()
# loop through bar
for i in range(len(bar)):
# loop through foo
for j in range(len(foo)):
# loop through elements of foo
for k in range(len(foo[j])):
# check if data in foo matches element in bar
if bar[i] == foo[j][k]:
# check if data in foo is the last element in the sub-list
if (len(foo[j]) > k+1):
pay[bar[i]] = foo[j][k+1]
else:
pay[bar[i]] = '-'
else:
pass
# iterate through dict and print its contents
for k, v in pay.items():
print(k, v)
def get_next(elt, sublist):
try:
return sublist[sublist.index(elt) + 1]
except:
return '-'
final_dict = { elt: get_next(elt, sub) for sub in foo for elt in sub if elt in bar}
print(final_dict) # {'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}
Just another solution using generators:
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
from itertools import chain
def get_pairs(it):
stack = None
while True:
try:
x = stack if stack else next(it)
try:
y = next(it)
if y.isdigit():
yield x, y
stack = None
else:
yield x, "-"
stack = y
except StopIteration:
yield x, "-"
break
except StopIteration:
break
result = dict([item for item in get_pairs(chain.from_iterable(foo))])
print(result)
Which yields
{'A': '1', 'C': '5', 'D': '9', 'E': '-', 'F': '-', 'G': '-', 'H': '-'}

Python - Is there a way to append multiple values to one key?

I have a list of numbers and values for each number. What I want to do is check if the number already exists in a dictionary and if it does, append the value to that list of values for the specific key.
For an Example
0
a
2
b
3
c
0
d
7
e
What I want to achieve is to populate a dictionary where the numbers would be the keys and letters would be the values.However in the event that the number 0 comes up again I want to take the value of the second 0 and append it to my list of values.
Basically the outcome would be
"0" : [a,d]
"2" : [b]
"3" : [c]
"7" : [e]
Right now im in the process of the following:
num_letter_dict = {}
num = ['0', '2', '3', '0','7']
letters = ['a', 'b', 'c', 'd','e']
for line in num:
if line in num_letter_dict:
num_letter_dict[line].append(letters)
else:
num_letter_dict[line] = [letters]
print(num_letter_dict)
This is the result I am getting
{'0': [['a', 'b', 'c', 'd', 'e']]}
{'0': [['a', 'b', 'c', 'd', 'e']], '2': [['a', 'b', 'c', 'd', 'e']]}
{'0': [['a', 'b', 'c', 'd', 'e'], ['a', 'b', 'c', 'd', 'e']], '2': [['a', 'b', 'c', 'd', 'e']]}
{'0': [['a', 'b', 'c', 'd', 'e'], ['a', 'b', 'c', 'd', 'e']], '2': [['a', 'b', 'c', 'd', 'e']], '3': [['a', 'b', 'c', 'd', 'e']]}
{'0': [['a', 'b', 'c', 'd', 'e'], ['a', 'b', 'c', 'd', 'e']], '2': [['a', 'b', 'c', 'd', 'e']], '3': [['a', 'b', 'c', 'd', 'e']], '7': [['a', 'b', 'c', 'd', 'e']]}
You're appending letters, which by itself is a full list. Instead, you want to append the element in letter that corresponds to the index of the key you're looking at in the num list.
for idx, line in enumerate(num):
if line in num_letter_dict:
num_letter_dict[line].append(letters[idx]) # append the element
else:
num_letter_dict[line] = [letters[idx]]
Result:
>>> print(num_letter_dict)
{'0': ['a', 'c'], '2': ['b'], '3': ['d'], '7': ['e']}
You just need to append the individual letter to the relevant list inside the dictionary, and not the whole list of letters. The zip function will loop over corresponding values from the two input lists as shown:
num_letter_dict = {}
num = ['0', '2', '3', '0','7']
letters = ['a', 'b', 'c', 'd','e']
for n, letter in zip(num, letters):
if n not in num_letter_dict:
num_letter_dict[n] = []
num_letter_dict[n].append(letter)
print(num_letter_dict)
Gives:
{'0': ['a', 'c'], '3': ['d'], '7': ['e'], '2': ['b']}
I think this can help you.
num_letter_dict = {}
num = ['0', '2', '0', '3','7']
letters = ['a', 'b', 'c', 'd','e']
for value, line in zip(letters,num):
if line in num_letter_dict:
num_letter_dict[line].append(value) # append the element
else:
num_letter_dict[line] = [value]
Try the following code, I have modified the for loop and used extend
for i, letter in zip(num, letters):
if i not in num_letter_dict:
num_letter_dict[i] = []
num_letter_dict[i].extend(letter) #change over here
print(num_letter_dict)
Ahh, I had to deal with this same issue yesterday. While the other submitted answers would work, might I recommend the defaultdict from the Collections module?
from collections import defaultdict
num = ['0', '2', '3', '0','7']
letters = ['a', 'b', 'c', 'd','e']
num_letter_dict = defaultdict(list)
for n, letter in zip(num, letters):
num_letter_dict[n].append(letter)
print(num_letter_dict)
I like this approach because it allows the defaultdict class to do the construction of the list internally, rather than muddying up one's own source code with if-statements.
You can test-execute this solution on IDEOne: https://ideone.com/9Dg9Rk

Python Morse Code: S.O.S

I am having trouble finishing this code. My original plan was to accept a long string as input , for example '... ---.. -. -.. .... . .-.. .--.' and then be able to use morse_code = [code_input.split(' ')] to separate them and run them individually but I am either getting the first character returning from the index or no return at all so can anyone help me mend this or help lead me in the way of a simpler solution?
Thanks to all for any help!
#morse code converter
def main():
code_input = get_input()
morse_code(code_input)
def get_input():
return input('Enter morse code: ')
def morse_code(code_input):
morse_code = [code_input]
convert = ['--..--', '.-.-.-', '..--..', '-----', '.----', '..---', '...--', '....-', '.....', '-....', '--...', '---..',
'----.', '.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....', '..', '.---' ,'-.-', '.-..', '--', '-.', '---',
'.--.', '--.-', '.-.', '...', '-', '..-', '...-', '.--', '-..-', '-.-', '--..']
new = [',', '.', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',]
print(morse_code)
length = len(morse_code)
for x in range(length):
for value in range(39):
if morse_code[x] == convert[value]:
print(new[value])
main()
Your idea to use split should work just fine:
>>> '... ---.. -. -.. .... . .-.. .--.'.split()
['...', '---..', '-.', '-..', '....', '.', '.-..', '.--.']
For the translation, I would use a dictionary instead of a list:
morse2text = {'...': 's', '---': 'o'}
To avoid key errors, I would a do a "safe lookup" using the dictionary get() method:
print( morse2text.get(m, m) )
Here is all the code put together (though with an incomplete dictionary) in case you want to build-off of a working example:
morse2text = {
'.-': 'a',
'-..': 'd',
'.': 'e',
'....': 'h',
'..': 'i',
'-.': 'n',
'---': 'o',
'...': 's',
'-': 't',
}
s = '... ---.. -. -.. .... . .-.. .--.'
for m in s.split():
print( morse2text.get(m, m) )
This should work for you:
def morse_code(code_input):
morse_codes = code_input.split(' ')
convert = ['--..--', '.-.-.-', '..--..', '-----', '.----', '..---', '...--', '....-', '.....', '-....', '--...', '---..',
'----.', '.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....', '..', '.---' ,'-.-', '.-..', '--', '-.', '---',
'.--.', '--.-', '.-.', '...', '-', '..-', '...-', '.--', '-..-', '-.-', '--..']
new = [',', '.', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',]
print(morse_codes)
code = ''
for x in morse_codes:
index = convert.index(x)
code+=new[index]
return code
print morse_code('... ---.. -. -.. .... . .-.. .--.')
Output:
['...', '---..', '-.', '-..', '....', '.', '.-..', '.--.']
'S8NDHELP'
As the Legendary Raymond mentioned, dict type is a better option.
Try dict(zip(convert,new)) to make a dictionary for conversion.
d = {'--..--': ',', '....-': '4', '.....': '5', '-...': 'B', '-..-': 'X',
'.-.': 'R', '--.-': 'Q', '--..': 'Z', '.--': 'W', '..---': '2',
'.-': 'A', '..': 'I', '-.-.': 'C', '...--': '3', '-': 'T', '.': 'E',
'.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1',
'.--.': 'P', '-----': '0', '-.-': 'Y', '-..': 'D', '----.': '9',
'-....': '6', '.---': 'J', '---': 'O', '.-.-.-': '.', '--': 'M',
'-.': 'N', '....': 'H', '---..': '8', '...-': 'V', '--...': '7',
'--.': 'G', '..-.': 'F'}
To use the dict:
translation = ''
for c in morse_codes:
translation += d[c]

merge complex matrix with python

I have a complex matrix that looks like this:
[[ ['x', '1', '2', '3', '4'],
['y', '5', '6', '7', '8']],
[ ['x', 'a', 'b', 'c', 'd'],
['y', 'e', 'f', 'g', 'h'] ] ]
I want to turn it into this:
['x', '1a', '2b', '3c', '4d'],
['y', '5e', '6f', '7g', '8h']
I'm busting my head but not managing to achieve the result. Also, even though I only have two groups of nested 5-items long lists, in theory I want to solve this for an infinite number of groups of the same size.
You can use a dict here:
>>> from operator import add
>>> lis = [[ ['x', '1', '2', '3', '4'],
['y', '5', '6', '7', '8']],
[ ['x', 'a', 'b', 'c', 'd'],
['y', 'e', 'f', 'g', 'h'] ] ]
>>> dic = {}
for item in lis:
for x in item:
k, v = x[0], x[1:]
if k in dic:
dic[k] = map(add, dic[k], v)
else:
dic[k] = v
...
>>> dic
{'y': ['5e', '6f', '7g', '8h'], 'x': ['1a', '2b', '3c', '4d']}
#list of lists
>>> [[k] + v for k, v in dic.iteritems()]
[['y', '5e', '6f', '7g', '8h'], ['x', '1a', '2b', '3c', '4d']]
Another solution using zip, reduce and a list comprehension:
>>> from operator import add
>>> def func(x, y):
... return map(add, x, y[1:])
>>> [[item[0][0]] + reduce(func, item[1:], item[0][1:]) for item in zip(*lis)]
[['x', '1a', '2b', '3c', '4d'], ['y', '5e', '6f', '7g', '8h']]
Here's a "fun" solution. Since you did not provide any information about your array's structure, I assumed the easiest variant:
import numpy
a = numpy.array([[
['x', '1', '2', '3', '4'],
['y', '5', '6', '7', '8']],
[
['x', 'a', 'b', 'c', 'd'],
['y', 'e', 'f', 'g', 'h']]],
dtype=numpy.object)
res = a[0].copy()
for chunk in a[1:]:
res[:,1:] += chunk[:,1:]
print(res)

Categories

Resources