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
Related
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']
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)
I have a list of n lists. Each internal list contains a combination of (a) strings, (b) the empty list, or (c) a list containing one string. I would like to transform the inside lists so they only contain the strings.
I have a list like this for example:
[[[],["a"],"a"],[["ab"],[],"abc"]]
and I would like it to be like this:
[["","a","a"],["ab","","abc"]]
I know I could probably go through with a loop but I am looking for a more elegant solution, preferably with a list comprehension.
List comprehension:
>>> original = [[[],["a"],"a"],[["ab"],[],"abc"]]
>>> result = [['' if not item else ''.join(item) for item in sublist] for sublist in original]
>>> result
[['', 'a', 'a'], ['ab', '', 'abc']]
As every element of the list that you'd like to flatten is iterable, instead of checking of being instance of some class (list, string) you can actually make use of duck-typing:
>> my_list = [[[],["a"],"a"],[["ab"],[],"abc"]]
>> [list(map(lambda x: ''.join(x), elem)) for elem in my_list]
Or more readable version:
result = []
for elem in my_list:
flatten = map(lambda x: ''.join(x), elem)
result.append(list(flatten))
Result:
[['', 'a', 'a'], ['ab', '', 'abc']]
It's quite pythonic to not to check what something is but rather leverage transformation mechanics to adaptive abilities of each of the structure.
Via list comprehension:
lst = [[[],["a"],"a"],[["ab"],[],"abc"]]
result = [ ['' if not v else (v[0] if isinstance(v, list) else v) for v in sub_l]
for sub_l in lst ]
print(result)
The output:
[['', 'a', 'a'], ['ab', '', 'abc']]
original_list = [[[],["a"],"a"],[["ab"],[],"abc"]]
flatten = lambda x: "" if x == [] else x[0] if isinstance(x, list) else x
flattened_list = [[flatten(i) for i in j] for j in original_list]
UPDATE: Sorry guys, I meant to say a list, within a list.
How do I split items in a list, within another list, using a delimiter. For example:
x = [['temp1_a','temp2_b', None, 'temp3_c'],['list1_a','list2_b','list3_c']]
Ideally, I would like to split them into a dictionary, so:
y = ['temp1','temp2', None, 'temp3','list1','list2','list3']
z = ['a','b', None, 'c','a','b','c']
I'm sure it uses split, but when I try using it, I get 'list' object has no attribute 'split'.
Use list_comprehension.
>>> x = ['temp1_a','temp2_b', None, 'temp3_c']
>>> y, z = [i if i is None else i.split('_')[0] for i in x ], [i if i is None else i.split('_')[1] for i in x ]
>>> y
['temp1', 'temp2', None, 'temp3']
>>> z
['a', 'b', None, 'c']
Update:
>>> x = [['temp1_a','temp2_b', None, 'temp3_c'],['list1_a','list2_b','list3_c']]
>>> y, z = [i if i is None else i.split('_')[0] for i in itertools.chain(*x)], [i if i is None else i.split('_')[1] for i in itertools.chain(*x) ]
>>> y
['temp1', 'temp2', None, 'temp3', 'list1', 'list2', 'list3']
>>> z
['a', 'b', None, 'c', 'a', 'b', 'c']
Here is how I would do it using list comprehensions:
xp = [(None,)*2 if i is None else i.split('_') for i in x]
y, z = map(list, zip(*xp))
The right-hand side expression on the second line is just an elegant way of writing:
[i[0] for i in xp], [i[1] for i in xp]
There are many ways to do this...
>>> from itertools import chain
>>> y, z = zip(*([None]*2 if not i else i.split('_') for i in chain(*x)))
>>> y
('temp1', 'temp2', None, 'temp3', 'list1', 'list2', 'list3')
>>> z
('a', 'b', None, 'c', 'a', 'b', 'c')
It's that time of the night, so I thought I'd write a recursive python 3 generator.
def flatten_list(a_list):
for element in a_list:
if isinstance(element, list):
yield from flatten_list(element)
else:
yield element
# {"temp1": "a", "temp2": "b"...}
values = dict(string.split('_')
for string in flatten_list(x)
if string is not None)
Say I have two lists:
list1 = ['a', 'b']
list2 = ['cat', 'dog', 'bird']
Whats the best way to get rid of any items in list2 that contain any of the substrings in list1? (In this example, only 'dog' would remain.)
You can use list comprehension with any() operator. You go through the items of second list, if any of items(charachters) in list1 is in the selected word, we don't take it. Otherwise, we add it.
list1 = ['a', 'b']
list2 = ['cat', 'dog', 'bird']
print [x for x in list2 if not any(y for y in list1 if y in x)]
Output:
['dog']
You can use filter() as well.
print filter(lambda x: not any(y for y in list1 if y in x), list2)
You can use regular expressions to do the job.
import re
pat = re.compile('|'.join(list1))
res = []
for str in list2:
if re.search(pat, str):
continue
else:
res.append(str)
print res