How to concatenate the list elements - python

Here I'm having the list of list, i want to concatenate only the first two elements if the second element of list has name. else do nothing.
The below is the code which i tried:
lst_1 = [['ANTWERP' 'BRIDGE', '05', 'N'],
['NORTHERN' 'VIGOUR', '05', 'N'],
['BRIDGE', '98', 'N']]
for i in lst_1:
for j in i:
j[0:2] = ['_'.join(j[0:2])]
expected output:
[['ANTWERP_BRIDGE', '05', 'N'],
['NORTHERN_VIGOUR', '05', 'N'],
['BRIDGE', '98', 'N']]
can i find any way to do this?

I wouldn't over think it, simply just concatenate the elements then add on the rest
[[f"{i[0]}_{i[1]}" if len(i) == 4 else i[0], *i[-2:]] for i in lst_1]

First you need to decide what it means for the second element to be a name. I suggest two possibilities. One is to check the length of the sub-list:
if len(i) == 4:
Another is to check for integers:
if len(i) > 2 and not i[1].isdigit():
In either case, you can merge pretty much as you did before, but with an if instead of the inner for loop:
for i in lst_1:
if <condition>:
i[:2] = ['_'.join(i[:2])]
This modifies lst_1 in-place. If you want to replace it with a new object, use #Sayse's answer.

Related

Del list and next list element in list if string exist

I have an example:
list = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
for i in range(len(list)):
if list[i][-1] == "last":
del(list[i+1])
del(list[i])
I'd like to delete this list where the last item is "last" and the next item on the list.
In this example there is a problem every time - I tried different configurations, replacing with numpy array - nothing helps.
Trackback:
IndexError: list index out of range
I want the final result of this list to be ['3', '4', 'next']
Give me some tips or help how I can solve it.
Try this:
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
delete_next = False
to_ret = []
for x in l:
if x[-1] == 'last':
delete_next = True
elif delete_next:
delete_next = False
else:
to_ret.append(x)
Using a variable to store if this needs to be deleted
Loop over the list, if the last element of that iteration == 'last' then skip, else, append to a new list.
Also, it is not recommended to edit lists while iterating over them as strange things can happen, as mentioned in the comments above, like the indexes changing.
l = [['2 a', 'nnn', 'xxxx','last'], ['next, next'], ['3', '4', 'next']]
newlist = []
for i in l:
if i[-1] == 'last':
continue
else:
newlist.append(i)

How to print a list of strings using yields

could you please tell me how to have the following output using the code below?
Input list:
list_1 = ["A","house","49","apartment","AD","Luke","17","17","Mike","8","B","Eliz","22","www.odeon.com","64", "holidays"]
Code:
def splitting(N):
for i in len(list_name):
yield list_name[i:i + N]
Expected output:
1st group: ["A","house","49","apartment","AD"]
2nd group: ["Luke","17","17","Mike","8"]
3rd group: ["B","Eliz","22","www.odeon.com","64"]
4th group: ["holidays]
I have followed most of the previous questions that have been already published in stackoverflow, but I am still having difficulties. Since it might be a duplicated question, I would like to ask if it would be possible to help me to figure out with this function and the expected output before closing. Most of you have experience with Python: I am a beginner with lots of questions and with the necessity of asking a couple of them to learn more, even by my own mistakes.
Thank you
You can use a for loop with a skip and then yield slices:
list_1 = ["A","house","49","apartment","AD","Luke","17","17","Mike","8","B","Eliz","22","www.odeon.com","64", "holidays"]
def splitting(a_list, N):
for i in range(0, len(a_list), N):
yield a_list[i:i + N]
for item in splitting(list_1, 5):
print(item)
Prints:
['A', 'house', '49', 'apartment', 'AD']
['Luke', '17', '17', 'Mike', '8']
['B', 'Eliz', '22', 'www.odeon.com', '64']
['holidays']
Right now, i is being incremented by one each time. So the second yield will return with ['house', '49', ...] (a total of N items). Instead, you want i to be incremented by N each time. You can accomplish that like this:
def splitting(N):
i = 0
while i < len(list_name) - N:
yield list_name[i:i + N] # while condition prevents IndexError
i = i + N
if i < len(list_name):
yield list_name[i:] # Yield what remains of the list

Compare elements in a list of lists in python and finding a match

I have a list of lists in Python with each list containing 5 elements. For example
lists = [['x1', 'y1', 'z1', '10', ''],
['x1', 'y1', 'z1', '', '5'],
['x2', 'y2', 'z2', '10', ''],
['x2', 'y2', 'z2', '10', ''],
['x1', 'y1', 'z1', '', '5'],
['x3', 'y3', 'z3', '', '40'],
['x2', 'y2', 'z2', '', '20']]
I wanted to compare the first 3 elements of each lists and if there is a match, then for the matched lists, I wanted to add the 4th column of every rows and compare it with the sum of 5th column of matched lists. I will need to output the rows if there is a match in the sum of 4th and 5th columns in the set of matched lists.
So in the above example, output should be
output = [['x1', 'y1', 'z1', '10', '10'],
['x2', 'y2', 'z2', '20', '20']]
Can someone provide a solution for this.
Thanks
A one-line solution!
output = [l[:4] + [str(sum(int(j[4]) for j in lists if j[:3] == l[:3] and j[4]))] for l in (l for l in lists if l[3])]
which gives output as:
[['x1', 'y1', 'z1', '10', '10'], ['x2', 'y2', 'z2', '20', '20']]
Instead of trying to explain that line, I have expanded the process into a larger for-loop Scroll down for a proper explanation of how it is working.
output = []
for l in (l for l in lists if l[3]):
sm = 0
for j in lists:
if j[:3] == l[:3] and j[4]:
sm += int(j[4])
sm = str(sm)
if sm == l[3]:
output.append(l[:4] + [sm])
how?
Well, we are looping through the lists in the generator: l for l in lists if l[3]. Essentially, we just want to start looping through the lists that actually have a value in the third index so that we can sum up the other lists which have the same first three elements and compare this to l[3].
We then declare a sum variable (sm) as 0 which we will add the other lists elements to.
Next we want to begin looping through the other lists in lists which may have the same first three elements.
We then check if the first three elements are the same (j[:3] == l[:3]) and also check if there is actually something to add to the sum in the fourth element (otherwise we will get an error when trying to convert an empty string to an int). Then, if it passes this test, we add j[4] to sm and continue onto the next list.
Next we convert the sum (sm) to a string since that is the data type it needs to be in the end and saves converting l[3] to an integer.
Finally we compare this string to the fourth element in our original list - if it is the same, then we append the original list along with the sum (using list concatenation) to the output list.

Using list.index with duplicate items inside the list in Python

I'm working in python 3.4
I have a problem with a piece in a program that is supposed to return all nested lists which first value is the biggest value.
I first tried the following code:
L = [['5','4','3'], ['23', '40', '8'], ['33', '24', '29'], ['33', '24', '29'],
['13', '66', '54'], ['5', '4', '3']]
BigNumFirst = []
for i in L:
if i[0] > i[1] and i[0] > i[2]:
BigNumFirst.append(L.index(i))
print(BigNumFirst)
And got the following output:
[0, 2, 2, 0]
As you can see the problem is that list.index() only returns the first matching nested list, so the index for the duplicate nested lists is not correct. I want the output to be:
[0, 2, 3, 5]
I can't figure out how I should solve this, at first I thought I could just add a variable that kept count of how many of a duplicate that existed inside of
BigNumFirst
but that of course only works if there's only one nested list with duplicates as my attempt showed:
BigNumFirst = []
NumbOfCopys=0
for i in L:
if i[0] > i[1] and i[0] > i[2]:
if L.index(i) in BigNumFirst:
NumbOfCopys+=1
BigNumFirst.append(L.index(i)+NumbOfCopys)
print(BigNumFirst)
output:
[0, 2, 3, 2]
As you can see the last number is still wrong. So, how would I do to make my program "know" what index a nested list has, even if it is a duplicate of a previous nested list?
Simply you can use enumerate and list comprehension :
>>> [i for i,j in enumerate(L) if max(j)==j[0]]
[0, 2, 3, 5]

Python list operation

I have two lists ListA and ListB as follow:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
I am trying to come up with List C which has the same length as List A but replace the numbers in the List A with 'X' if the number is in the List B.The result i am expecting:
ListC=['X','X','2','2','2','3','4','4','X','X','X','X']
FYI, length of ListB will always less than the length of ListA and ListB will not hold any numbers that is not in List A.
I have tried like this:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
ListC=[]
for items in ListB:
for a in ListA:
if items==a:
ListC.append('X')
else:
ListC.append(a)
obviously this will create a List that has (length of listB X lenght A) rather than just just the length of list A. Is there any built in function that does this operation? Could anyone give me a clue how to do it?
You can use a list comprehension:
[i if i not in ListB else 'X' for i in ListA]
To fix your current code, use in to check to see if the item is in ListB:
for item in ListA:
if item in ListB:
ListC.append('X')
else:
ListC.append(item)
Any time you are doing membership tests over and over on the same list, it's a good idea to create a set. Although it takes some time to construct the set the individual lookups can be much faster
SetB = set(ListB)
[i if i not in SetB else 'X' for i in ListA]
List Comprehension is your friend on this one:
ListA=['1','1','2','2','2','3','4','4','5','5','5','5']
ListB=['1','5']
ListC = [i if i not in ListB else 'x' for i in ListA]
--> ['x', 'x', '2', '2', '2', '3', '4', '4', 'x', 'x', 'x', 'x']
Hope this helps!

Categories