Add two lists in Python - python

I am trying to add together two lists so the first item of one list is added to the first item of the other list, second to second and so on to form a new list.
Currently I have:
def zipper(a,b):
list = [a[i] + b[i] for i in range(len(a))]
print 'The combined list of a and b is'
print list
a = input("\n\nInsert a list:")
b = input("\n\nInsert another list of equal length:")
zipper(a,b)
Upon entering two lists where one is a list of integers and one a list of strings I get the Type Error 'Can not cocanenate 'str' and 'int' objects.
I have tried converting both lists to strings using:
list = [str(a[i]) + str(b[i]) for i in range(len(a))]
however upon entering:
a = ['a','b','c','d']
b = [1,2,3,4]
I got the output as:
['a1','b2','c3','d4']
instead of what I wanted which was:
['a+1','b+2','c+3','d+4']
Does anyone have any suggestions as to what I am doing wrong?
N.B. I have to write a function that will essentially perform the same as zip(a,b) but I'm not allowed to use zip() anywhere in the function.

Zip first, then add (only not).
['%s+%s' % x for x in zip(a, b)]

What you should do
You should use
list = [str(a[i]) +"+"+ str(b[i]) for i in range(len(a))]
instead of
list = [str(a[i]) + str(b[i]) for i in range(len(a))]
In your version, you never say that you want the plus character in the output between the two elements. This is your error.
Sample output:
>>> a = [1,2,3]
>>> b = ['a','b','c']
>>> list = [str(a[i]) +"+"+ str(b[i]) for i in range(len(a))]
>>> list
['1+a', '2+b', '3+c']

Related

Reordering elements of lists in a list of lists

I have a list of lists composed of elements that are strings and integers, e.g.
a = [['i','j',1,2,3...n], ['k','l',4,5,6...n], ['m','n',7,8,9...n]]
I would like to reorder the string elements in each sub list such that a[l][1] takes the place of a[l][0] and vice versa, so I end up with:
a = [['j','i',1,2,3...n], ['l','k',4,5,6...n], ['n','m',7,8,9...n]]
I have tried iterating through each sub list and using an order variable to change the integer positions, but it does not seem to change the ordering in each list:
order = [1,0,2,3,4...n]
for l in reversed(range(len(a))):
[a[l][j] for j in order]
What am I doing wrong?
[a[l][j] for j in order]
This is just an expression that is evaluated and then discarded.
If you want to change a, you need to assign to it:
a[l] = [a[l][j] for j in order]
The simplest for the concrete issue would be slice assignment in a loop:
for sub in a:
sub[:2] = reversed(sub[:2])
With your general order approach, you could do:
for sub in a:
sub[:] = [sub[i] for i in order] # needs to mutate the actual object!
just use this code:
a[1][1], a[1][0] = a[1][0] , a[1][1]
thanks to python

Filtering a list of two-element sublists with a list comprehension

I have a list of lists
input = [[2,13],[5,3],[10,8],[13,4],[15,0],[17,10],[20,5],[25,9],[28,7],[31,0]]
I want to write a list comprehension where for the [a,b] pairs above I get the pairs where b > a. In the above example that would be [2,13].
My attempt
x = [[item[i],[j]] for item in inputArray if j>i]
produces a NameError
NameError: name 'j' is not defined`
The problem with your attempt is that you never tell Python what i and j are supposed to be. The check j > i cannot be computed and the list [item[i],[j]] can't be built without that information.
You can issue
>>> inp = [[2,13],[5,3],[10,8],[13,4],[15,0],[17,10],[20,5],[25,9],[28,7],[31,0]]
>>> [[a, b] for a, b in inp if b > a]
[[2, 13]]
This solution does not produce a NameError because for a, b in inp tells Python to iterate over the elements of inp (two-element sublists) and in each iteration assign the name a to the first element of a sublist and the name b to the second element.
I used the name inp instead of input because the latter is already taken by a builtin function for getting user input.
Explanation of the list comprehension
The comprehension is equivalent to
>>> result = []
>>> for a, b in inp:
... if b > a:
... result.append([a, b])
...
>>> result
[[2, 13]]
Every two-element list in inp is unpacked into the variables a and b. If the filter condition b > a is True, then a list [a, b] is built and included in the final result.
If you don't want to use unpacking, you can also index into the sublists of inp like this:
>>> [sub[:] for sub in inp if sub[1] > sub[0]]
[[2, 13]]
Taking a full slice of sub via sub[:] ensures that like in the other solutions presented so far, the filtered result stores (shallow) copies of the sublists of inp. If copying it not necessary, you can omit the [:].
This code does not produce a NameError because for sub in inp tells Python to iterate over inp and in each iteration assign the name sub to the next sublist. In addition, explicit numbers (0 and 1) are used for the indices.
Personally, I prefer the solution with unpacking. It is easier to read and will run even if the elements of inp don't support indexing, but are iterables from which two elements can be extracted.
You should unpack each pair into the i, j variables, and then you can compare them:
x = [[i, j] for i,j in inputList if j > i]
(note I have renamed inputArray, inputList)
Or without unpacking:
x = [item for item in inputList if item[1] > item[0]]

Join elements of an arbitrary number of lists into one list of strings python

I want to join the elements of two lists into one list and add some characters, like so:
list_1 = ['some1','some2','some3']
list_2 = ['thing1','thing2','thing3']
joined_list = ['some1_thing1', 'some2_thing2', 'some3_thing3']
however i don't know in advance how many lists I will have to do this for, i.e. I want to do this for an arbitrary number of lists
Also, I currently receive a list in the following form:
list_A = [('some1','thing1'),('some2','thing2'),('some3','thing3')]
so I split it up into lists like so:
list_B = [i for i in zip(*list_A)]
I do this because sometimes I have an int instead of a string
list_A = [('some1','thing1',32),('some1','thing1',42),('some2','thing3', 52)]
so I can do this after
list_C = [list(map(str,list_B[i])) for i in range(0,len(list_B)]
and basically list_1 and list_2 are the elements of list_C.
So is there a more efficient way to do all this ?
Try this if you are using python>=3.6:
[f'{i}_{j}' for i,j in zip(list_1, list_2)]
If you using python3.5, you can do this:
['{}_{}'.format(i,j) for i,j in zip(list_1, list_2)]
also you can use this if you don't want to use formatted string:
['_'.join([i,j]) for i,j in zip(list_1, list_2)]
You can join function like this on the base list_A, itself, no need to split it for probable int values:
list_A = [('some1','thing1',32),('some1','thing1',42), ('some2','thing3', 52)]
["_".join(map(str, i)) for i in list_A]
Output:
['some1_thing1_32', 'some1_thing1_42', 'some2_thing3_52']
Update:
For you requirement, where you want to ignore last element for last tuple in your list_A, need to add if-else condition inside the list-comprehension as below:
["_".join(map(str, i)) if list_A.index(i) != len(list_A)-1 else "_".join(map(str, i[:-1])) for i in list_A ]
Updated Output:
['some1_thing1_32', 'some1_thing1_42', 'some2_thing3']
For ignoring the last element of every tuple in list_A, I found this to be the quickest way:
["_".join(map(str, i)) for i in [x[:-1] for x in list_A] ]

python get list of partial strings from list of tuples

I have a list of tuples, its dates and times, from;to
print datetime
gives
[(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
I want to make a new list, but only of the 'to' times:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']
I cant seem to put all the elements together, so far I have
for a in datetime:
for b in a:
enddates = [b[b.find(";")+1:] for b in a]
print enddates
gives the last result only, not the list
[u'2017-09-10-13-45-23']
Have not given up easily, but down a rabbit hole on this
you don't need any loop, just pick the first & unique item from each tuple, and perform str.partition on it (take 2nd element: the rightmost one), in a list comprehension like you tried
a = [(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
enddates = [b[0].partition(";")[2] for b in a]
print(enddates)
result:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']
With str.split() function:
dt = [(u'2017-09-10-14-00-35;2017-09-10-14-15-46',), (u'2017-09-10-13-45-23;2017-09-10-14-00-35',), (u'2017-09-10-13-30-05;2017-09-10-13-45-23',)]
result = [d[0].split(';')[1] for d in dt]
print(result)
Or the same with str.rfind() function:
...
result = [d[0][d[0].rfind(';')+1:] for d in dt]
The output:
['2017-09-10-14-15-46', '2017-09-10-14-00-35', '2017-09-10-13-45-23']

python if statement to check a column for a value and do a command

for z in range(0,countD.shape[0]):
if countD[z,0] in background_low1[:,0]:
background_lowCountD.append(countD[z,:])
else:
background_goodCountD.append(countD[z,:])
I'm using the above code and getting a "list indices must be integers, not tuple" error message. I have two uneven arrays (CountD and background_low1), If a value is present in column 0 of both arrays at any row level I want to move that row to a new array, if its only present in 1 I want that row moved to a second new array.
You are getting this error message because lists are unidimensional (in theory). But since a list can contain another list, you can create a multidimensional list. Now accessing an element of a list is done using an index (which must be an integer) between brackets. When dealing with multidimensional lists, just use multiple brackets one after the other :
>>> a = ['a','b','c']
>>> b = [1,2,a]
>>> print b[2]
>>> ['a','b','c']
>>> print b[2][0]
>>> 'a'
So, to answer your question, try something like this :
list1 = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
list2 = [[1,4,5,6],
[7,6,7,8],
[9,1,2,3]]
newList = []
otherList = []
#you need to make sure both lists are the same size
if len(list1) == len(list2):
for i in range(len(list1)):
if list1[i][0] == list2[i][0]:
newList.append(list1[i])
else:
otherList.append(list1[i])
#the lists should now look like this
>>> print newList
>>> [[1,2,3,4],[9,10,11,12]]
>>> print otherList
>>> [[5,6,7,8]]

Categories