Check the elements of the lists - python

a = ["000000001111111110101010","111111110000111111000011"]
what I need to do is check my list(a),
for item in a:
for elements in range(len(a[item])):
if "0" in a or "1" in a:
random change one elements in a[item](0 change to 1 or 1 change to 0) just one element,how can I do this
in my question if all elements changed should be:
a = ["111111110000000001010101","000000001111000000111100"]
if just one elements changed should be:
a =["000000001111101110101010","111111110000111111001011"]
just random pick 0 or 1 to change to 1 or 0

The source code below works for me:
a = ['000000001111111110101010',"111111110000111111000011"]
print(a)
ret = []
for item in a:
r = ''
for i in item:
b = int(i, base=2)
c = str(int(not b))
r = r + c
ret.append(r)
print(ret)
And the output is:
['000000001111111110101010', '111111110000111111000011']
['111111110000000001010101', '000000001111000000111100']

Here are both, flipping all digits and flipping one random digit:
import random
def flip_all(s):
s = list(s)
return ''.join([str(1 - int(c)) for c in s])
def flip_one(s):
s = list(s)
rand_i = random.randint(0, len(s)-1)
s[rand_i] = str(1 - int(s[rand_i]))
return ''.join(s)
a = ["000000001111111110101010","111111110000111111000011"]
print("a: ", a)
print("flip all: ", [flip_all(word) for word in a])
print("flip one: ", [flip_one(word) for word in a])
Output:
a: ['000000001111111110101010', '111111110000111111000011']
flip all: ['111111110000000001010101', '000000001111000000111100']
flip one: ['000000001101111110101010', '111111110000111110000011']

Related

Weaving Numbers In Python

I am trying to write a code which returns a list of all possible woven numbers from two user inputted numbers.
For Example,
if A = 27 and B = 54 then there are four numbers that can be woven
2574
5247
7425
4752
Weaving a number can be done by weaving from the beginning, starting with A, weaving from the beginning, starting with B, weaving from the end, starting with A, weaving from the end, starting with B. While weaving two numbers A and B, if all the digits of A are weaved and some more digits are there in B, the remaining digits of B are just appended at the end.
I am trying
num_a = input()
num_b = input()
weaved_nums = []
def permutations(string):
if len(string) == 1:
return string
recursive_perms = []
for c in string:
for perm in permutations(string.replace(c,'',1)):
recursive_perms.append(c+perm)
return set(recursive_perms)
num_a_perms = list(permutations(num_a))
num_b_perms = list(permutations(num_b))
def weave(num_1, num_2):
new_string = ''
for i in range(len(min([num_1, num_2], key = len))):
new_string += num_1[i] + num_2[i]
new_string += max(num_1, num_2, key=len)[len(num_1):]
weaved_nums.append(new_string)
for i in range(len(num_a_perms)):
for k in range(len(num_b_perms)):
weave(num_a_perms[i], num_b_perms[k])
weave(num_b_perms[k], num_a_perms[i])
print(weaved_nums)
However my program returns
['2475', '4257', '2574', '5247', '7425', '4752', '7524', '5742']
for inputs
27 and 54
Another solution - limited to two inputs:
start at the beginning r first: zip(r,s)
start at the end r first: zip(r[::-1],s[::-1])
start at the beginning s first: zip(s,r)
start at the end s first: zip(s[::-1],r[::-1])
def f(r,s):
combos = ((r,s),(r[::-1],s[::-1]),(s,r),(s[::-1],r[::-1]))
for combo in combos:
yield ''.join(c for x,y in zip(*combo) for c in (x,y))
for thing in f('27','54'):
print(thing)
For strings of unequal length use itertools.zip_longest(*combo,fillvalue='') instead of zip.
def f(r,s):
combos = ((r,s),
(r[::-1],s[::-1]),
(s,r),
(s[::-1],r[::-1]))
for combo in combos:
yield ''.join(c for x,y in itertools.zip_longest(*combo,fillvalue='') for c in (x,y))
>>> for thing in f('27','543'):
print(thing)
25743
73245
52473
37425
num_a = input("Enter first term:")
num_b = input("Enter second term:")
weaved_nums = []
def weave(num_1, num_2):
new_string = ''
for i in range(min(len(num_1), len(num_2))):
new_string += num_1[i] + num_2[i]
new_string += max(num_1, num_2, key=len)[min(len(num_1), len(num_2)):]
weaved_nums.append(int(new_string))
weave(num_a, num_b)
weave(num_b, num_a)
weave(num_a[::-1], num_b[::-1])
weave(num_b[::-1], num_a[::-1])
print(max(list(map(int, weaved_nums))))
This Solution Works

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 subtract 2 string or list in python?

I have very large strings in my codes. I would like to detect different characters between the strings. Here is an example what I mean:
a='ababaab'
b='abaaaaa'
a=a-b
print(a)
I expect kind of like these; 'bb' or '000b00b'
I know sounds weird but I really need this.
You could do:
a = 'ababaab'
b = 'abaaaaa'
a = ''.join(x if x != y else '0' for x, y in zip(a, b))
# '000b00b'
# OR
a = ''.join(x for x, y in zip(a, b) if x != y)
# 'bb'
Here is the example: It works wih list
listA = ["a","b"]
listB = ["b", "c"]
listC = [item for item in listB if item not in listA]
print listC
Output
# ['c']
You can create custom function as following:
(assumption length of both strings are equal)
def str_substract(str1, str2):
res = ""
for _ in xrange(len(str1)):
if str1[_] != str2[_]:
res += str1[_]
else:
res += "0"
return res
a='ababaab'
b='abaaaaa'
print str_substract(a, b)
output:
000b00b
result = ''
for temp in a:
result += temp if temp not in b else '0'
Use zip:
res = ''
for i, j in zip(a, b):
if i == j:
res += '0'
else:
res += i
Using a list to store the result is probably more efficient.
if you want s1 - s2 :
s1 = 'ababaab'
s2 = 'abaaaaa'
for i,j in zip(s1,s2):
if (i != j):
print i,
output : bb

Brute Force password generator for md5? [duplicate]

I would like to make a alphabetical list for an application similar to an excel worksheet.
A user would input number of cells and I would like to generate list.
For example a user needs 54 cells. Then I would generate
'a','b','c',...,'z','aa','ab','ac',...,'az', 'ba','bb'
I can generate the list from [ref]
from string import ascii_lowercase
L = list(ascii_lowercase)
How do i stitch it together?
A similar question for PHP has been asked here. Does some one have the python equivalent?
Use itertools.product.
from string import ascii_lowercase
import itertools
def iter_all_strings():
for size in itertools.count(1):
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
for s in iter_all_strings():
print(s)
if s == 'bb':
break
Result:
a
b
c
d
e
...
y
z
aa
ab
ac
...
ay
az
ba
bb
This has the added benefit of going well beyond two-letter combinations. If you need a million strings, it will happily give you three and four and five letter strings.
Bonus style tip: if you don't like having an explicit break inside the bottom loop, you can use islice to make the loop terminate on its own:
for s in itertools.islice(iter_all_strings(), 54):
print s
You can use a list comprehension.
from string import ascii_lowercase
L = list(ascii_lowercase) + [letter1+letter2 for letter1 in ascii_lowercase for letter2 in ascii_lowercase]
Following #Kevin 's answer :
from string import ascii_lowercase
import itertools
# define the generator itself
def iter_all_strings():
size = 1
while True:
for s in itertools.product(ascii_lowercase, repeat=size):
yield "".join(s)
size +=1
The code below enables one to generate strings, that can be used to generate unique labels for example.
# define the generator handler
gen = iter_all_strings()
def label_gen():
for s in gen:
return s
# call it whenever needed
print label_gen()
print label_gen()
print label_gen()
I've ended up doing my own.
I think it can create any number of letters.
def AA(n, s):
r = n % 26
r = r if r > 0 else 26
n = (n - r) / 26
s = chr(64 + r) + s
if n > 26:
s = AA(n, s)
elif n > 0:
s = chr(64 + n) + s
return s
n = quantity | r = remaining (26 letters A-Z) | s = string
To print the list :
def uprint(nc):
for x in range(1, nc + 1):
print AA(x,'').lower()
Used VBA before convert to python :
Function AA(n, s)
r = n Mod 26
r = IIf(r > 0, r, 26)
n = (n - r) / 26
s = Chr(64 + r) & s
If n > 26 Then
s = AA(n, s)
ElseIf n > 0 Then
s = Chr(64 + n) & s
End If
AA = s
End Function
Using neo's insight on a while loop.
For a given iterable with chars in ascending order. 'abcd...'.
n is the Nth position of the representation starting with 1 as the first position.
def char_label(n, chars):
indexes = []
while n:
residual = n % len(chars)
if residual == 0:
residual = len(chars)
indexes.append(residual)
n = (n - residual)
n = n // len(chars)
indexes.reverse()
label = ''
for i in indexes:
label += chars[i-1]
return label
Later you can print a list of the range n of the 'labels' you need using a for loop:
my_chrs = 'abc'
n = 15
for i in range(1, n+1):
print(char_label(i, my_chrs))
or build a list comprehension etc...
Print the set of xl cell range of lowercase and uppercase charterers
Upper_case:
from string import ascii_uppercase
import itertools
def iter_range_strings(start_colu):
for size in itertools.count(1):
for string in itertools.product(ascii_uppercase, repeat=size):
yield "".join(string)
input_colume_range = ['A', 'B']
input_row_range= [1,2]
for row in iter_range_strings(input_colume_range[0]):
for colum in range(int(input_row_range[0]), int(input_row_range[1]+1)):
print(str(row)+ str(colum))
if row == input_colume_range[1]:
break
Result:
A1
A2
B1
B2
In two lines (plus an import):
from string import ascii_uppercase as ABC
count = 100
ABC+=' '
[(ABC[x[0]] + ABC[x[1]]).strip() for i in range(count) if (x:= divmod(i-26, 26))]
Wrap it in a function/lambda if you need to reuse.
code:
alphabet = ["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"]
for i in range(len(alphabet)):
for a in range(len(alphabet)):
print(alphabet[i] + alphabet[a])
result:
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
...

Levenshtein distance in python giving only 1 as edit distance

I have a python program to read two lists (one with errors and other with correct data). Every element in my list with error needs to be compared with every element in my correct list. After comparing i get all the edit distance between every compared pair. now i can find the least edit distance for the given error data and thru get my correct data.
I am trying to use levenshtein distance to calculate the edit distance but its returning all edit distance as 1 even which is wrong.
This means the code for calculating levenshtein distance is not correct. I am struggling to find a fix for this. HELP!
My Code
import csv
def lev(a, b):
if not a: return len(b)
if not b: return len(a)
return min(lev(a[1:], b[1:])+(a[0] != b[0]), lev(a[1:], b)+1, lev(a, b[1:])+1)
if __name__ == "__main__":
with open("all_correct_promo.csv","rb") as file1:
reader1 = csv.reader(file1)
correctPromoList = list(reader1)
#print correctPromoList
with open("all_extracted_promo.csv","rb") as file2:
reader2 = csv.reader(file2)
extractedPromoList = list(reader2)
#print extractedPromoList
incorrectPromo = []
count = 0
for extracted in extractedPromoList:
if(extracted not in correctPromoList):
incorrectPromo.append(extracted)
else:
count = count + 1
#print incorrectPromo
for promos in incorrectPromo:
for correctPromo in correctPromoList:
distance = lev(promos,correctPromo)
print promos, correctPromo , distance
There is a Python package available that implements the levenshtein distance : python-levenshtein
To install it:
pip install python-levenshtein
To use it:
>>> import Levenshtein
>>> string1 = 'dsfjksdjs'
>>> string2 = 'dsfiksjsd'
>>> print Levenshtein.distance(string1, string2)
3
The implementation is correct. I tested this:
def lev(a, b):
if not a: return len(b)
if not b: return len(a)
return min(lev(a[1:], b[1:])+(a[0] != b[0]), lev(a[1:], b)+1, lev(a, b[1:])+1)
print lev('abcde','bc') # prints 3, which is correct
print lev('abc','bc') # prints 1, which is correct
Your problem, as I noticed by your comments, is probably when you call the method:
a = ['NSP-212690']
b = ['FE SV X']
print lev(a,b) # prints 1 which is incorrect because you are comparing arrays, not strings
print lev(a[0],b[0]) # prints 10, which is correct
So, what you can do is:
Before the call to "lev(a,b)", extract the first element of each array
def lev(a, b):
if not a: return len(b)
if not b: return len(a)
return min(lev(a[1:], b[1:])+(a[0] != b[0]), lev(a[1:], b)+1, lev(a, b[1:])+1)
a = ['NSP-212690']
b = ['FE SV X']
a = a[0] # this is the key part
b = b[0] # and this
print lev(a,b) # prints 10, which is correct
Anyway, I would not recommend you that recursive implementation, because the performance is veeeery poor
I would recommend this implementation instead (source: wikipedia-levenshtein)
def lev(seq1, seq2):
oneago = None
thisrow = range(1, len(seq2) + 1) + [0]
for x in xrange(len(seq1)):
twoago, oneago, thisrow = oneago, thisrow, [0] * len(seq2) + [x + 1]
for y in xrange(len(seq2)):
delcost = oneago[y] + 1
addcost = thisrow[y - 1] + 1
subcost = oneago[y - 1] + (seq1[x] != seq2[y])
thisrow[y] = min(delcost, addcost, subcost)
return thisrow[len(seq2) - 1]
or maybe this slightly modified version:
def lev(seq1, seq2):
if not a: return len(b)
if not b: return len(a)
oneago = None
thisrow = range(1, len(seq2) + 1) + [0]
for x in xrange(len(seq1)):
twoago, oneago, thisrow = oneago, thisrow, [0] * len(seq2) + [x + 1]
for y in xrange(len(seq2)):
delcost = oneago[y] + 1
addcost = thisrow[y - 1] + 1
subcost = oneago[y - 1] + (seq1[x] != seq2[y])
thisrow[y] = min(delcost, addcost, subcost)
return thisrow[len(seq2) - 1]

Categories

Resources