Concatenate two lists using condition - python

I need to concatenate lists A and B using condition that two lists transform to list C, with the same length, but each i element doesn't change position and list is sorted. Else return empty list:
A = ['a', 'b', 'c']
B = ['x', 'y', 'z']
concatenated to: C = ['a', 'b', 'z'].
or
A = ['8', '2', '3']
B = ['1', '2', '0']
concatenated to: C = ['1', '2', '3'].
I absolutely have no idea how I can start solve my problem. Which algorithm I have to use?
UPD:
Another examples:
A = ['a', 'b', 'c']
B = ['x', 'x', 'x']
result is: ['a', 'b', 'x']
A = ['b', 'a']
B = ['x', 'c']
result must be: ['b', 'c'].
And result of concatenation of these two lists is an empty list:
A = ['e','a'],
B = ['f','b']

Do you just need to switch the last two elements in each list? If so, this is a simple way that lets you see what is going on.
lst1 = ['a', 'b', 'c']
lst2 = ['x', 'x', 'x']
lst3 = lst1
lst3[len(lst2)-1] = lst2[len(lst2)-1]
lst3
Out: ['a', 'b', 'x']
Else, explain the logic behind what you are trying to do a little more.

This can be done with a greedy algorithm, iterate over both list and take the minimum value that is greater from the previous item you had taken.
prev = None
A = ['a', 'b', 'c']
B = ['x', 'x', 'x']
n = len(A)
result = []
for i in range(n):
mn, mx = A[i],B[i]
if mx<mn:
mn,mx = mx,mn
if prev == None or mn >= prev:
prev = mn
result.append(prev)
elif mx >= prev:
prev = mx
result.append(prev)
else:
print "can't be done"
break
if len(result) == n:
print result

Related

How to check if elements of a list are alternating?

I have lists like this, and I want to know if their elements are alternating. For example:
list1 = ['A', 'C', 'A', 'C', 'A', 'C'] # result = True
list2 = ['A', 'A', 'A', 'C', 'A', 'C'] # result = False
list3 = ['A', 'C', 'C', 'C', 'A', 'C'] # result = False
list4 = ['A', 'C', 'A', 'C', 'A', 'A'] # result = False
Elements of the list will always be a string.
The length of this string is not fixed.
The list will always contain only two distinct values.
Now, How to check if elements of list are alternating in Python?
Try this Code:
a = ['A','C','A','C','A','C']
print((len(set(a[::2])) == 1) and (len(set(a[1::2])) == 1))
Example:
lists = [
['A','C','A','C','A','C'],
['A','A','A','C','A','C'],
['A','C','C','C','A','C'],
['A','C','A','C','A','A']
]
for i in lists:
print((len(set(i[::2])) == 1) and (len(set(i[1::2])) == 1))
Edit: based on Daniel Hao's commments:
for sub in lists:
print(all(x!= y for x, y in zip(sub, sub[1:])))
Output:
True
False
False
False
Tell me if its not working...

How do i rename duplicate elements in python list of lists based on vertical position?

I have a list of lists like this:
listofLists = [
['a', 'b', 'e'],
['a', 'd'],
['a', 'c'],
['a', 'b', 'c', 'e'],
['a', 'e', 'c', 'f']
]
How can i read this element list vertically and rename duplicates appending numbers to the element in incremental order? The output list has to preserve the same order.
For example, first position of 'e' is at index 1 in list ['a', 'e', 'c', 'f'], it should remain as it is. Next position of 'e' is at index 2 in list ['a', 'b', 'e'] which should be renamed as 'e1'. The last position of 'e' is in list ['a', 'b', 'c', 'e'] which should be renamed as 'e3'
The required output should be:
requiredOutput = [['a', 'b', 'e1'],
['a', 'd'],
['a', 'c'],
['a', 'b', 'c1', 'e2'],
['a', 'e', 'c1', 'f']]
The code i have tried is as below, by checking against a transposed list. But it does not give me the required output since my code changes the current element of the list. I dont know if this is the right approach to the problem statement.
transformedListOfTuples = list(zip_longest(*listofLists))
transformedListOfList= [list(x) for x in transformedListOfTuples]
for i in range(0, len(listofLists)):
for j in range(0, len(listofLists[i])):
pos = -1
for z in range(0, len(transformedListOfList)):
if listofLists[i][j] in transformedListOfList[z]:
pos = pos + 1
if pos == 0:
continue
elif pos > 0:
listofLists[i][j] = listofLists[i][j] + str(pos)
elif listofLists[i][j] not in transformedListOfList[z]:
continue
How about this:
arr = [
['a', 'b', 'e'],
['a', 'd'],
['a', 'c'],
['a', 'b', 'c', 'e'],
['a', 'e', 'c', 'f']
]
listOfRepeated = []
max_len = 0
for i in range(0, len(arr)):
if max_len < len(arr[i]):
max_len = len(arr[i])
for j in range(0, max_len):
list_to_add = []
for i in range(0, len(arr)):
if j < len(arr[i]):
val = arr[i][j]
# For each iteration of `i`, you'll go down the group
if not val in list_to_add:
list_to_add.append(val)
count = listOfRepeated.count(val)
if count > 0:
arr[i][j] = ""+str(val)+""+str(count)
for element in list_to_add:
listOfRepeated.append(element)
for list in arr:
print(list)
Output:
['a', 'b', 'e1']
['a', 'd']
['a', 'c']
['a', 'b', 'c1', 'e2']
['a', 'e', 'c1', 'f']
Explanation:
j is the counter to go horizontally, i is the counter to go down the group. Every element is present at arr[i][j]
list_to_add is a list that contains every unique character for a particular group
listOfRepeated is a list of every element that has been seen so far. If you're present in listOfRepeated once, that means your current group is the first one with the character. If it is more than once, that means you need to add a number after the character.
you can use:
previous = {}
for i in range(max(len(e) for e in listofLists)):
col = [l[i] for l in listofLists if len(l) > i]
previous.update({e: previous.get(e, 0) + 1 for e in set(col)})
for l in listofLists:
if len(l) > i:
if previous[l[i]] > 1:
l[i] = l[i] + str(previous[l[i]] - 1)
listofLists
output:
[['a', 'b', 'e1'],
['a', 'd'],
['a', 'c'],
['a', 'b', 'c1', 'e2'],
['a', 'e', 'c1', 'f']]
how it works: previous dict will store the current number of occurrences of an element per columns, the first for loop iterate over all columns, at each iteration step the previous dict it is updated base on the elements from the current column, the inner for loop will update each element from the current column if the number of occurrences per columns is more than 1
or you can use:
from itertools import accumulate, zip_longest
from collections import Counter
cols = list(zip_longest(*listofLists))
t = [[f'{e}{a[e] - 1}' if e and a[e] > 1 else e for e in i] for i, a in
zip(cols, accumulate((Counter(set(l)) for l in cols)))]
listofLists = [[e[i] for e in t if e[i]] for i in range(len(t[0]))]
you operate per column and get the transpose of your desired output (this is t)

merge nested list by first value in each list in python

I have a version of this code working but it seems overly complex. This is the simplified version im getting stuck on. in python3.
list1 = [['a', 'b'], ['a', 'c'], ['a', 't'], ['x', 'f'], ['x', 'g'], ['d', 'z']]
z = len(list1)
for i in range(0, z):
for j in range(i + 1, z):
while list1[i][0] == list1[j][0]:
list1[i] = list1[i] + [list1[j][-1]]
if list1[j] in list1:
list1.remove(list1[j])
z = z - 1
I want output.
[['a', 'b', 'c', 't'], ['x', 'f', 'g'], ['d', 'z']]
Modding Darryl's a bit:
d = {}
for head, *tail in lst:
d.setdefault(head, [head]).extend(tail)
lst2 = list(d.values())
A simplfied construction is the following two steps.
d = {}
for sublist in lst:
d.setdefault(sublist[0], []).extend(sublist[1:])
lst2 = [[k] + v for k, v in d.items()]
print(lst2)
>>> [['a', 'b', 'c', 't'], ['x', 'f', 'g'], ['d', 'z']]
Explanation
(1) Dictionary d places items with the same first element as a dictionary key, with values corresponding to the remaining elements to produce:
{'a': ['b', 'c', 't'], 'x': ['f', 'g'], 'd': ['z']}
(2) Next, the list comprehension uses the key of each dictionary entry as the first element of a sublist and the value of the items as the remaining elements to produce the desired result

python remove element from nested list if it exists in another list +

lets say I have a list:
A = ['x', 'y', 'z']
and another one - nested:
B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]
how can I remove 'z' from the last sublist in list B based on the knowledge that 'z' is in A and also every first element [0] of the sublist B is in list A ?
so basically i need to detele all elements from such a nested list where element is in A and where it not stands in the first position of that nested list ?
I am trying this but get stacked:
for i in B:
for j in i[1:]:
if j in A:
del j
but I am missing something.
You can use a nested list comprehension:
>>> [sub[:1]+[i for i in sub[1:] if not(sub[0] in A and i in A)] for sub in B]
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]
Here you'll preserve the items from sublists (from second item to end) that doesn't met your conditions for deleting.
Use a list comprehension to update a list in-place:
for sublist in B:
if sublist[0] in A:
sublist[1:] = [v for v in sublist[1:] if v not in A]
j in your loop is only another reference to a value in a sublist. del j removes that one reference, but the list still contains that reference. You can remove values from the list with del listobj[index] or listobj.pop(value) (watch for subtleties in what those mean), but deleting from a list while iterating over it will result in items being skipped if you are not careful.
By assigning to a slice, you replace those elements in the list itself, in-place.
Note that you probably want to make A a set; membership testing is far faster when using a set:
Aset = set(A)
for sublist in B:
if sublist[0] in Aset:
sublist[1:] = [v for v in sublist[1:] if v not in Aset]
Demo:
>>> A = ['x', 'y', 'z']
>>> B = [['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c', 'z']]
>>> Aset = set(A)
>>> for sublist in B:
... if sublist[0] in Aset:
... sublist[1:] = [v for v in sublist[1:] if v not in Aset]
...
>>> B
[['x', 'a', 'b', 'c'], ['y', 'c'], ['x', 'a', 'c']]

Find the same elements from two lists and print the elements from both lists

There are two lists:
k = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'e']
l = ['a', 'c', 'e']
I want to find the same elements from these two lists, that is:
['a', 'c', 'e']
then I want to print out the element we found, for example, 'a' from both lists, that is: ['a', 'a', 'a'].
The result I want is as follows:
['a', 'a', 'a', 'c', 'c', 'c', 'e', 'e']
I try to doing in this way:
c = []
for item_k in k:
for item_j in j:
if item_k== item_j:
c.append(item_k)
c.append(item_j)
However, the result is ['a', 'a', 'c', 'c', 'e', 'e']
Also in this way:
c=[]
for item_k in k:
if item_k in l:
c.append(item_k)
d=l.count(item_k)
c.append(item_k*d)
print c
But it do not works, can anybody tell me how to do it? really appreciate your help in advance
result = [x for x in sorted(k + l) if x in k and x in l]
print(result)
results:
['a', 'a', 'a', 'c', 'c', 'c', 'e', 'e']
Since you want to pick up elements from both lists, the most straight forward way is probably to iterate over both while checking the other one (this is highly optimizatiable if you depend on speed for doing this):
merged = []
for el in list1:
if el in list2:
merged.append(el)
for el in list2:
if el in list1:
merged.append(el)
.. if the order of the elements is important, you'll have to define an iteration order (in what order do you look at what element from what array?).
If the lists are sorted and you want the result to be sorted:
sorted([x for x in list1 if x in set(list2)] + [x for x in list2 if x in set(list1)] )
You can use set operations to intersect and then loop through, appending to a new list any that match the intersected list
k = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'e']
l = ['a', 'c', 'e']
common_list = list(set(k).intersection(set(l)))
all_results = []
for item in k:
if item in common_list:
all_results.append(item)
for item in l:
if item in common_list:
all_results.append(item)
print sorted(all_results)
output:
['a', 'a', 'a', 'c', 'c', 'c', 'e', 'e']
Here's a compact way. Readability might suffer a little, but what fun are comprehensions without a little deciphering?
import itertools
k = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'e']
l = ['a', 'c', 'e']
combined = [letter for letter in itertools.chain(k,l) if letter in l and letter in k]
Here is an implementation that matches your initial algorithm:
k = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'e']
l=['a', 'c', 'e']
c=[]
for x in l:
count = 0
for y in k:
if x == y:
count += 1
while count>=0:
c.append(x)
count = count -1
print c

Categories

Resources