I'm trying to merge two lists based on the following rules:
The first element in list1 should be merged with the last element in list2, the second element in list1 should be merged with second last element in list2 and so on.
If an element in list1/list2 is None, then the corresponding element in the other list should be kept as it is in the merged list.
I feel I may have to use a linked list here, but I'm not sure. I'm trying to figure out the solution by looping over the lists, but I'm not able to figure out the logic here.
def merge_list(list1, list2):
merged_data=""
new_str=""
#write your logic here
for l1 in list1:
for l2 in list2[::-1]:
if l1 is None or l2 is None:
pass
else:
new_str = l1+l2
i=list2.index(l2)
print(new_str)
break
#return resultant_data
list1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
list2=['y','tor','e','eps','ay',None,'le','n']
merged_data=merge_list(list1,list2)
print(merged_data)
Expected Output:
“An apple a day keeps the doctor away”
You can use zip to iterate through two lists simultaneously:
def merge_list(lst1,lst2):
s = ''
for x, y in zip(lst1, lst2[::-1]):
if y and x:
s += x + y
elif x:
s += x
elif y:
s += y
s += ' '
return s[:-1]
list1 = ['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
list2 = ['y','tor','e','eps','ay',None,'le','n']
merged_data = merge_list(list1,list2)
print(merged_data)
# An apple a day keeps the doctor away
You can shorten this and use a list-comprehension, like below (but, I would prefer the other which is more readable):
def merge_list(lst1,lst2):
return ' '.join(x + y if x and y else x if x else y for x, y in zip(lst1, lst2[::-1]))
Assuming both lists have the same length
>>> list1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
>>> list2=['y','tor','e','eps','ay',None,'le','n']
>>> ' '.join([l1 + l2 if l1 and l2 else l1 if l1 and not l2 else l2 for l1, l2 in zip(list1, reversed(list2)) if l1 and l2])
'An apple a day keeps the doctor away'
Make sure the lists are in same length then just a zip is enough. But replace None value with '' (empty string)
["".join(row) for row in zip(list1, reversed(list2))]
=>
['An', 'apple', 'a', 'day', 'keeps', 'the', 'doctor', 'away']
First use list comprehensions to merge the two lists and then convert that list into string.
" ".join(str(x) for x in [list1[i]+list2[len(list2)-1-i] if list2[len(list2)-1-i] != None else list1[i] for i in range(len(list1))])
'An apple a day keeps the doctor away'
def fetch_index(list2, item_index):
x = list2[::-1]
return x[item_index]
def merge_list(list1, list2):
list_3 = []
#write your logic here
for l1 in list1:
l2 = fetch_index(list2, list1.index(l1))
if l1 is None and l2 is None:
pass
elif l1 is None:
list_3.append(l2)
elif l2 is None:
list_3.append(l1)
else:
list_3.append(l1+l2)
return(list_3)
list1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
list2=['y','tor','e','eps','ay',None,'le','n']
x = merge_list(list1,list2)
print ' '.join(i for i in x)
A longer version if you don't want to use zip
A short answer without using zip.
" ".join([list1[x]+[y if y is not None else '' for y in list2 ][::-1][x] for x in range(len(list1)-1)]
list1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
list2=['y','tor','e','eps','ay',None,'le','n']
a=list2.remove(None)
list2.insert(5,"")
list3 = [ str(x[0]) + x[1] for x in zip(list1, list2[::-1]) ]
print ' '.join(list3)
output:
An apple a day keeps the doctor away
l1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
l2=['y','tor','e','eps','ay',None,'le','n']
a=l2[::-1]
l3=[]
for i in range(len(l1)):
if(l1[i] is None or a[i] is None):
l3.append(l1[i])`enter code here`
else:
l3.append(l1[i]+a[i])
print(" ".join(l3))
def merge_list(list1, list2):
merged_data = ""
list3 = list1
for i in range(1, 2*len(list2) + 1,2): #Converting both lists in single list
list3.insert(i, list2[-1]) # Adding last elements of list2 at alternate to positions elements of list3
list2.pop() #Removing the last element from list2
list3 = ["" if i is None else i for i in list3] # Handling NoneType condition. If there is "None", convertted to ""
for i in range(0,len(list3),2):
word="".join(list3[i:i+2]) #joining the elements in set of two
merged_data=merged_data+word+" " #converting above word into one
return merged_data
list1=['A', 'app','a', 'd', 'ke', 'th', 'doc', 'awa']
list2=['y','tor','e','eps','ay',None,'le','n']
s=''
new=''
for i in list1:
for j in list2[::-1]:
if i==None:
i=''
elif j==None:
j=''
new=i+j
s=s+new+' '
list2.pop(-1)
break
print(s)
Related
I have an issue with lists, I have a list lst =['ab', 'cd', 'ef']. Now I want to add a string ('are')to end of each string value of the list. I tried but it is getting added letter by letter, how to add the whole word to end of each string value in the list?
My code:
lst =['ab', 'cd', 'ef']
b = 'are'
new_list = [el1+'_'+el2 for el2 in b for el1 in lst]
It gives:
new_list = ['ab_a', 'cd_a', 'ef_a','ab_r', 'cd_r', 'ef_r','ab_e', 'cd_e', 'ef_e']
Excepted output:
new_list = ['ab_are', 'cd_are', 'ef_are']
Rather than iterate on the second string just append like
new_list = [el1+'_'+ b for el1 in lst]
Try this:
lst =['ab', 'cd', 'ef']
b = 'are'
new = ["_".join([item, b]) for item in lst]
# ['ab_are', 'cd_are', 'ef_are']
You are iterating through both list and string. Just iterate through the list:
lst =['ab', 'cd', 'ef']
b = 'are'
new_list = [el + '_' + b for el in lst]
print(new_list)
Output:
['ab_are', 'cd_are', 'ef_are']
Just iterate in list
lst = ["ab", "cd", "ef"]
b = "are"
iterated_list = [i + " " + b for i in lst]
print(iterated_list)
Another option would be the following below:
lst = ["ab", "cd", "ef"]
b = "are"
iterated_list = []
for i in lst:
iterated_list.append(i + " " + b)
print(iterated_list)
List1 = ['RELEASE', 'KM123', 'MOTOR', 'XS4501', 'NAME']
List2 = ['KM', 'XS', 'M']
Now I am using code that only searches List2 in List1 in any position.
Result = [ s for s in List1 if any(xs in s for xs in List2]
Output :
[KM123', 'MOTOR', 'XS4501', 'NAME']
But I don't want 'NAME' to be in the list because it contains 'M' not in the starting. Any help...
Use str.startswith() which checks if a string starts with a particular sequence of characters:
[s for s in List1 if any(s.startswith(xs) for xs in List2)]
Looks like you can use str.startswith
Ex:
List1 = ['RELEASE', 'KM123', 'MOTOR', 'XS4501', 'NAME']
List2 = ('KM', 'XS', 'M') #convert to tuple
result = [ s for s in List1 if s.startswith(List2)]
print(result) #-->['KM123', 'MOTOR', 'XS4501']
def merge_list(list1,list2):
res_list=[]
list2=list2.reverse()
conv = lambda i : i or ''
res = [conv(i) for i in list2]
for i in range(0,len(list1)):
res_list.append(list1[i]+list2[i])
merged_data=' '.join(res_list)
return merged_data
list1 = ['A', 'app', 'a', 'd','ke','th','doc','awa']
list2=['y','tor','e','eps','ay',None,'le','n']
data=merge_list(list1,list2)
data
I'm trying to reverse list2 and concatenate the strings from both the lists to get a string as result. The objective is to ignore None in the list if there is any, and print the final sentence.
The error is that you have used
list2=list2.reverse()
the list.reverse() method reverses the list in place, the method itself returns None. To fix this, change the line to just read:
list2.reverse()
Also, you have used
res_list.append(list1[i]+list2[i])
This should probably read
res_list.append(list1[i]+res[i])
These corrections give the output:
'An apple a day keeps the doctor away'
Another way to solve this problem is as a one-liner, using zip, list slicing to reverse list2, and ternary statements to apply the None -> '' logic.
>>> list1 = ['A', 'app', 'a', 'd', 'ke', 'th', 'doc', 'awa']
>>> list2 = ['y', 'tor', 'e', 'eps', 'ay', None, 'le', 'n']
>>> ' '.join(''.join(y if y else '' for y in x) for x in zip(list1, list2[::-1]))
'An apple a day keeps the doctor away'
1) Replace None in both the lists:
>>> list1 = [x if x else "" for x in list1]
>>> list2 = [x if x else "" for x in list2]
2) zip and iterate:
>>> lis=[]
>>> for x,y in zip(list1,list2[::-1]):
... lis.append(x+y)
3) join:
>>> " ".join(lis)
'An apple a day keeps the doctor away'
CDJB's one liner combines all these steps
I have two list
List1 = ['hello','welcome','india','nation']
List2 = ['ind', 'nat','hellooo','welcomeeee']
i want to compare elements and print as below -
Output :
['india','nation','hello','welcome']
please suggest some optimized way.
I am having list with unspecified size in each, but it has one list elements matches another list elements, as random, i don't know the size of highest / longest possible match in any of the list.
You can use the Levenshtein distance to determine the closest match, so here is one implementation of Levenshtein:
def levenshteinDistance(s1, s2):
if len(s1) > len(s2):
s1, s2 = s2, s1
distances = range(len(s1) + 1)
for i2, c2 in enumerate(s2):
distances_ = [i2+1]
for i1, c1 in enumerate(s1):
if c1 == c2:
distances_.append(distances[i1])
else:
distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
distances = distances_
return distances[-1]
List1 = ['hello', 'welcome', 'india', 'nation']
List2 = ['ind', 'nat', 'helloooo', 'welcomeeeeee']
[min(zip(List1, [levenshteinDistance(j, i) for j in List1]), key=lambda x: x[1])[0] for i in List2]
#['india', 'nation', 'hello', 'welcome']
Similar to #AndreiDurnea's solution, you can also use a generator:
def comparer(L1, L2):
for i in L2:
for j in L1:
if (i in j) or (j in i):
yield j
List1 = ['hello','welcome','india','nation']
List2 = ['ind', 'nat','helloooo','welcomeeeeee']
res = list(comparer(List1, List2))
['india', 'nation', 'hello', 'welcome']
As per #pault's comment, itertools.product with a list comprehension may be more efficient than a generator:
from itertools import product
res = [j for i, j in product(List2, List1) if (i in j) or (j in i)]
List comprehension,
In [14]: [j for i in List2 for j in List1 if i in j or j in i]
Out[14]: ['india', 'nation', 'hello', 'welcome']
List1 = ['hello','welcome','india','nation']
List2 = ['ind', 'nat','helloooo','welcomeeeeee']
Rezult = []
for firstItem in List1:
for secondItem in List2:
if firstItem in secondItem or secondItem in firstItem:
Rezult.append(firstItem)
continue
print(Rezult)
the output for this is:
['hello', 'welcome', 'india', 'nation']
I would suggest to rename the variables:
list_1 = ['hello','welcome','india','nation']
list_2 = ['ind', 'nat','helloooo','welcomeeeeee']
rezult = []
for firstItem in list_1:
for secondItem in list_2:
if firstItem in secondItem or secondItem in firstItem:
rezult.append(firstItem)
print(rezult)
I got a list of 40 words which i took out of a txt file. I've found the duplicates, and replaced them with the same word but then with "*" infront and behind. The code looks like this:
def show(self, list1):
a = [x for x in list1 if list1.count(x) > 1]
lista2 = ["*"+s+"*" if s in a else s for s in list1]
print(lista2)
Input:
> ['utanför', 'dörren', 'stod', 'en', 'man', 'och', 'lyssnade', 'intensivt', 'i', 'den', 'mörka', 'korridoren', 'han', 'hade', 'skuggat', 'digby', 'groat', 'hela', 'eftermiddagen', 'och', 'följt', 'efter', 'honom', 'in', 'i', 'huset', 'när', 'han', 'fick', 'hära', 'ljudet', 'av', 'fotsteg', 'från', 'rummet', 'smög', 'han', 'sig', 'in', 'i']
Output:
> ['utanför', 'dörren', 'stod', 'en', 'man', '*och*', 'lyssnade', 'intensivt', '*i*', 'den', 'mörka', 'korridoren', '*han*', 'hade', 'skuggat', 'digby', 'groat', 'hela', 'eftermiddagen', '*och*', 'följt', 'efter', 'honom', '*in*', '*i*', 'huset', 'när', '*han*', 'fick', 'hära', 'ljudet', 'av', 'fotsteg', 'från', 'rummet', 'smög', '*han*', 'sig', '*in*', '*i*']
Note that the duplicates have a * infront and behind.
TL:DR I want the first duplicate to be ignored and the rest to be highlighted with * infront and behind.
Edit:
def show(self, list1):
new_list, seen = [], set()
for x in list1:
if x in seen:
new_list.append('*{0}*'.format(x))
else:
new_list.append(x)
seen.add(x)
print new_list
appears to work like a charm.
The only thing now that I want to add is to make it case sensitive. As in if "Han" and "han" have occured that it notices that it's a duplicate.
def show(self, list1):
new_list, seen = [], set()
for x in list1:
if x in seen:
new_list.append('*{0}*'.format(x))
else:
new_list.append(x)
seen.add(x)
print new_list
Use a set to keep a track of seen items:
>>> seen = set()
>>> new_lis = []
for x in lis:
if x in seen: #if item is present in the set `seen` then add the `*`'s
new_lis.append('*' + x + '*')
else:
seen.add(x) #item seen for the first time, add it to the set and the list
new_lis.append(x)
Using a generator function:
def solve(lis):
seen = set()
for item in lis:
if item in seen:
yield '*' + item + '*'
else:
seen.add(item)
yield item
>>> new_lis = list(solve(your_lis))
Iterate through and replace an element with the asterixed version if it appears in the sliced list. Keep track of current index with enumerate
lista2 = [s if s not in lista[:i] else '*'+s+'*' for i,s in enumerate(a)]