Too many values to unpack or 0 values to unpack - python

I have this code and I am trying to use the list splits
but either I get Too many values to unpack or need more than 0 values to unpack
def edits1(word):
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
temp1 = []
for i in splits:
temp = list(i)
for j in range(0,len(temp)):
temp1.append(temp[j])
splits = temp1
for s in splits:
print s
#here
deletes = [a + b[1:] for a, b in splits if b]
return set(deletes)

Related

How can you delete similar characters at the same positions in 2 strings

I need to figure out a way to delete common characters from two strings if the common characters are in the same position, but it is not working and I am trying to figure this out. This is what I tried so far, it works for some strings, but as soon as the second string is larger than the first, it stops working. EDIT: I also need a way to store the result in a variable before printing it as I need to use it in another function.
Example :
ABCDEF and ABLDKG would result in the "ABD" parts of both strings to be deleted, but the rest of the string would remain the same
CEF and LKG would be the output
def compare(input1,input2):
if len(input1) < len(input2):
for i in input1:
posi = int(input1.find(i))
if input1[num] == input2[num]:
x = input1.replace(i,"" )
y = input2.replace(i,"" )
num = num+1
print(x)
print(y)
else:
for i in input2:
num = 0
posi = int(input2.find(i))
if input2[num] == input1[num]:
input1 = input1[0:num] + input1[num+1:(len(input1)+ 1 )] # input1.replace(i,"" )
input2 = input2[0:num] + input2[num+1:(len(input1) + 1)]
x = input1
y = input2
num = num + 1
print(str(x))
print(str(y))
you could use
from itertools import zip_longest
a,b = "ABCDEF","ABLDKG"
[''.join(k) for k in zip(*[i for i in zip_longest(a, b, fillvalue = "") if i[0]!=i[1]])]
['CEF', 'LKG']
You can wrap this in a function:
def compare(a, b):
s = zip(*[i for i in zip_longest(a, b, fillvalue = "") if i[0]!=i[1]])
return [''.join(k) for k in s]
compare("ABCDEF","ABLDKG")
['CEF', 'LKG']
compare('asdfq', 'aqdexyz')
['sfq', 'qexyz']
strlist = ["ABCDEF","ABLDKG"]
char_dict = dict()
for item in strlist:
for char in item:
char_dict[char] = char_dict.get(char,0) + 1
new_strlist = []
for item in strlist:
new_strlist.append(''.join([char for char in item if char_dict[char] < 2]))
Note that this will convert strings that have only duplicates into empty strings rather than removing them altogether.

How can I find string variations in dictionary within a distance of 1?

Say you have scanned a document with names on it. Due to mistakes in the scanning process, you want to look up the names in a dictionary. Therefore, you need a function that takes in a possible name and outputs a list with every possible string variation of the input within a Levenshtein-Distance of 1.
I modified an implementation (https://rosettacode.org/wiki/Levenshtein_distance#Python) but didn't get the right result, yet. Since Levenshtein implementations usually take in two strings and compare them to give out an int for the L-Distance, I am wondering how to change that to get the variations of one string?
def levenshteinVariation(n_possible):
m = n_possible
n = n_correct
d = []
for i in range(len(m)+1):
d.append([i])
del d[0][0]
for j in range(len(n)+1):
d[0].append(j)
for j in range(1,len(n)+1):
for i in range(1,len(m)+1):
if m[i-1] == n[j-1]:
d[i].insert(j,d[i-1][j-1])
else:
minimum = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+2)
d[i].insert(j, minimum)
return d
The expected result would be a match in the dictionary to all variations within a L-Distance of 1.
for n_correct, n_possible in [('Marcus','Maacus'), ('David','Davide'), ('Steve', 'Steven')]:
print(f"{n_correct} found: {n_correct in levenshteinVariation(n_possible)}")
But I got:
Marcus found: False
David found: False
Steve found: False
Thanks to Dan D. I was able to solve it myself:
def Variations1(name):
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
splits = [(name[:i], name[i:]) for i in range(len(name) + 1)]
deletes = [L + R[1:] for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1]
replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
inserts = [L + c + R for L, R in splits for c in letters]
return set(deletes + transposes + replaces + inserts)

How to accumulate sum in each indexed element in loop[python]?

The loop goes through list of numbers. I need to use map to accumulate the sum of all element[0] in another list's element[0] , sum of all element[1] in element[1].
result_list = []
sub1 = sub2 = sub3 = 0 #these 3 should be only indexes 0,1,2 of list above
for item in r:
l = item.split(';') # originally l = '34;56;78'
q = list(map(float,l)) # q is the list of 3 elements
#instead of code below I want to have smth like
# result_list = list(map( sum( q(item), result_list)
sub1 += q[0]
sub2 += q[1]
sub3 += q[2]
Input:
l = [['1;2;3'], ['10;20;30'], ['12;34;56']]
result_list must aggregate the sum of all element[0] in each list to result_list[0].
Output
result_list[0] = 1+ 10 + 12
result_list[1] = 2 + 20 + 34
result_list[2] = 3 + 30 + 56
r is this, I omit names and calculate average of each 'column'.
Bawerman;55;79;50
Baldwin;83;62;72
Owen;94;86;65
Watson;92;79;100
Clifford;33;99;47
Murphy;94;87;53
Shorter;83;61;61
Bishop;27;89;41
This is one approach.
Ex:
l = [["1;2;3"], ["10;20;30"], ["12;34;56"]]
result_list = []
l = [list(map(float, j.split(";"))) for i in l for j in i]
for i in zip(*l):
result_list.append(sum(i))
print(result_list)
Output:
[23.0, 56.0, 89.0]
You could do something like this, assuming each element of l is a list of one string:
l = [['1;2;3'], ['10;20;30'], ['12;34;56']]
numbers = (map(float, e.split(';')) for e, in l)
result = [sum(n) for n in zip(*numbers)]
print(result)
Output
[23.0, 56.0, 89.0]
A oneliner can do the job:
If you need first to parse the strings with the numbers:
l = [[int(i) for i in e[0].split(';')] for e in l]
And after that, just:
result = map(sum, zip(*l))
csv.reader + zip + statistics.mean
I omit names and calculate average of each 'column'
You don't need to construct a large list of lists from your data. You can use an iterator and use sequence unpacking with zip. To calculate the mean, you can use statistics.mean:
from io import StringIO
from statistics import mean
import csv
x = StringIO("""Bawerman;55;79;50
Baldwin;83;62;72
Owen;94;86;65
Watson;92;79;100
Clifford;33;99;47
Murphy;94;87;53
Shorter;83;61;61
Bishop;27;89;41""")
# replace x with open('file.csv', 'r')
with x as fin:
reader = csv.reader(x, delimiter=';')
zipper = zip(*reader)
next(zipper) # ignore labels
res = [mean(map(float, x)) for x in zipper]
print(res)
# [70.125, 80.25, 61.125]

Looping a function over a list in Python

This Python function interlocks the characters of two words (e.g., "sho" + "col" -> "school"). word1-char1 + word2-char1 + word1-char2 + ...
def interlock(a,b):
i = 0
c = ""
d = ""
while (i < len(a) and len(b)):
c = (a[i]+b[i])
d = d + c
i+=1
return(d)
interlock("sho", "col")
Now, I would like to apply this function to a list of words. The goal is to find out any interlock corresponds to an item of a list.
word_list = ["test", "col", "tele", "school", "tel", "sho", "aye"]
To do that, I would first have to create a new list that has all the interlocks in it. This is exactly where I am stuck - I don't know how to iterate over word_list using interlock.
Thanks for your help!
If you want all possible permutations of the list to pass to interlock without pairing a word with itself i.e we won't get interlock("col", "col"):
def interlock(s1,s2):
out = ""
while s1 and s2: # keep looping until any string is empty
out += s1[0] + s2[0]
s1, s2 = s1[1:], s2[1:]
return out + s1 + s2 # add the remainder of any longer string
word_list = ["test", "col", "tele", "school", "tel", "sho","col" "aye"]
from itertools import permutations
# get all permutations of len 2 from our word list
perms = permutations(word_list,2)
st = set(word_list)
for a, b in perms:
res = interlock(a,b)
if res in st:
print(res)
school
You can also achieve the same result using itertools.zip_longest using a fillvalue of "" to catch the end of the longer words:
from itertools import permutations, zip_longest
perms = permutations(word_list, 2)
st = set(word_list)
for a, b in perms:
res = "".join("".join(tup) for tup in zip_longest(a,b,fillvalue=""))
if res in st:
print(res)
You can do it using product function from itertools module:
from itertools import product
for a, b in product(word_list, word_list):
interlock(a, b)
https://docs.python.org/2/library/itertools.html#itertools.product
Try this.
def interlockList(A):
while Len(A) > 2:
B = interlock(A[0],A[1])
A.remove(A[0])
A.remove(A[1])
A.insert(0, B)
return B

Session in GAE separated in comma's

sample i have a list:
sample = [a, b, c, d]
Then I want to pass the sample to the session:
self.session['sample'] = None #declaring the session...
for item in sample:
self.session['sample'] = str(self.session['sample']) + "," + str(item)
But the output is:
None, a, b, c, d
I want the value of my session['sample'] would be = a, b, c, d
You could do it in one line instead of a loop with join() and list comprehension:
self.session['sample'] = ", ".join(str(item) for item in sample)
If you're happy doing it in a loop, you need to make the first item "" instead of None:
self.session['sample'] = "" # Empty string
for item in sample:
self.session['sample'] += "," + str(item) # Note I've used += here
a += 1 is just a tidy way to write a = a + 1

Categories

Resources