Append some columns to a list of list matrix - python

I have some troubles in merging two list of lists to one. I think there is a simple solution, but I'm stuck for hours.
My two list of lists are for example:
a=[['1','2'],['3','4']]
b=[['5','6'],['7','8']]
And what I try to get is:
c=[['1','2','5','6'],['3','4','7','8']]
But I don't know how many rows and columns the lists have.
I tried to use the zip command but it produced something like:
[(['1','2'],['5','6']),(['3','4'],['7','8'])]
Thanks very much for any help on this issue!!!
Maybe something like How can I add an additional row and column to an array? would work but I suppose there is an simpler solution.

>>> a=[['1','2'],['3','4']]
>>> b=[['5','6'],['7','8']]
>>> [x + y for x, y in zip(a, b)]
[['1', '2', '5', '6'], ['3', '4', '7', '8']]

[sum(ai_bi, []) for ai_bi in zip(a, b)]
which scales to n lists of lists :
L = (a, b, ...)
[sum(el, []) for el in zip(*L)]

If the two lists are of the same length, you could use a simple loop:
listone = [['1','2'],['3','4']]
listtwo = [['5','6'],['7','8']]
newlist = []
for i in range(0, len(data)):
newlist.append(listone[i] + listtwo[i])
print(newlist)
[['1','2','5','6'],['3','4','7','8']]

If your lists have the same lenght:
c = []
for idx in range(len(a)):
c.append(a[idx]+b[idx])
Not very elegant though.

Related

Generating a list of lists in Python, but get the same ID of nested elements

So, I'm using this code:
list_of_lists = []
sample_list = ['1', '2', '3']
for x in range(3):
list_of_lists.append(sample_list)
print(id(list_of_lists[0][1]),
id(list_of_lists[1][1]),
id(list_of_lists[2][1]))
And the items in sublists, actually, are the same objects!
>140324175479088 140324175479088 140324175479088
If I want to change list_of_lists[0][1] to '0', all sublists will be changed accordingly.
Why is it so? How to generate a list_of_lists from sample_list in a right way to make items in each sublist independent?

Find index of an element in list using wildcards

I have a list like this:
a = [['1','2','3','a','b'],
['4','5','6','c','d'],
['7','8','9','e','f']]
I want to identify the index of an element in the list a based on first three sub-elements of the element. For example, the index of the element which contains ['4','5','6'] as its first three sub-elements is 1.
I have tried to do this using list comprehension follows:
ind = [i for i in range(0,len(a)) if (a[i][0] == '4' and a[i][1] == '5' and a[i][2] == '6')]
But this is computationally expensive as I have to implement this code several times in a for loop. So, I am looking for a less computationally expensive method. SO far I have tried 'list.index' as follows:
ind = a.index(['4','5','6','*','*'])
where '*' is used as wildcard string. But is does not work as it outputs:
['4', '5', '6', '.*', '.*'] is not in list
I think there is something wrong with the way I am using wildcard. Can you please tell me what is it? Or is there another fast way to identify the element of a list based on its sub-elements?
Solution 1: True wildcard
You can simply use a.index(...) if you use a true wildcard:
class Wildcard:
def __eq__(self, anything):
return True
a = [['1','2','3','a','b'],
['4','5','6','c','d'],
['7','8','9','e','f']]
wc = Wildcard()
print(a.index(['4', '5', '6', wc, wc]))
Outputs 1. Try it online!
This might be fast because 1) it does the searching in C code and 2) it does minimal work, as it for example doesn't create a list slice for every row and might often rule out a row simply by looking at just the first value.
Solution 2: operator.indexOf
Or using operator.indexOf, which finds the index in C rather than in Python like an enumerate solution would. Here are two versions of that, I suspect the one mapping a ready-to-go slice is faster:
from operator import indexOf, itemgetter
a = [['1','2','3','a','b'],
['4','5','6','c','d'],
['7','8','9','e','f']]
print(indexOf((r[:3] for r in a), ['4', '5', '6']))
print(indexOf(map(itemgetter(slice(3)), a), ['4', '5', '6']))
Try it online!
Well you could transpose and slice and transpose back and finally index, like this:
>>> list(zip(*list(zip(*a))[:3])).index(('4', '5', '6'))
1
>>>
But what's wrong with?
>>> [x[:3] for x in a].index(['4', '5', '6'])
1
>>>
It may be more efficient to implement it as a generator. In this way, if e.g. you know that you can get at most one match you can stop once it is found:
a = [['1','2','3','a','b'],
['4','5','6','c','d'],
['7','8','9','e','f']]
pattern = ['4','5','6']
def find_index(data, pattern):
for n, elt in enumerate(a):
if elt[:3] == pattern:
yield n
indices = find_index(a, pattern)
next(indices)
It gives:
1
Here's a fairly simple and straightforward way of accomplishing this:
def findListMatch(lists, match):
# Loop over lists with indices
for k, sublist in enumerate(lists):
# Check if the beginning of the list matches the desired start pattern
if sublist[0:len(match)] == match:
# If it's a match, return the index
return k
# If none of the lists match, return a placeholder value of "None"
return None
a = [['1','2','3','a','b'],
['4','5','6','c','d'],
['7','8','9','e','f']]
matchIndex = findListMatch(a, ['4', '5', '6'])
# Result:
# matchIndex = 1
#U12-Forward's answer works but unnecessarily builds a temporary list of the same size as the input list before applying the index method, which can be quite an overhead if the list is long. A more efficient approach would be to use enumerate to generate the indices while comparing the first 3 items to the desired list:
next(i for i, l in enumerate(a) if l[:3] == ['4', '5', '6'])

Comparing all elements of 2 lists with Python 2

I have 2 lists: a = ['5', '2', '3', '4'], and b = ['1', '6', '7', '5']. Using Python 2, how can I compare each list element in a to each element in b? (i.e. is a[0] == b[0], is a[0] == b[1], etc).
I know that I could just write out numerous if statements, but I hope that there is a more elegant way to do this.
After checking each list element, I want to know how many times a shared value was found (in my example lists above, it would be one time, '5').
EDIT: This is not a duplicate, b/c i am comparing two different lists to each other, while the possible duplicate dealt with only 1 list.
The count() method of list may help:
>>> a = ['5', '2', '3', '4']
>>> b = ['1', '6', '7', '5']
>>> for item in a:
... print item, b.count(item)
...
5 1
2 0
3 0
4 0
Probably faster for big inputs than eugene y's, as it only needs to iterate over b once,
instead of len(a) times:
from collections import Counter
counts = Counter(b)
for i in a:
print(i, counts[i])
If you are only concerned with shared values, and not with their positions or counts, convert them to set and use intersection:
>>> a = ['5','2','3','4']
>>> b = ['1','6','7','5']
>>> set(a).intersection(b)
{'5'}
If you want to retain how often the elements appear in the intersection, you can also do an intersection of collections.Counter using &
>>> a = ['5','2','3','4','1','1','6','5']
>>> b = ['1','6','7','5','5']
>>> collections.Counter(a) & collections.Counter(b)
Counter({'5': 2, '1': 1, '6': 1})
Note: This is different from the solution by #GingerPlusPlus in that it is symmetric, i.e. if 5 is present once in list a and twice in list b, then the shared count will be 1, not 2.
def cmp(*lists):
lists_len_min = list(map(lambda x: len(x), lists))
if min(lists_len_min) != max(lists_len_min):
raise Exception("Lists must have equal length")
iterator = iter(lists)
last = next(iterator)
for element in iterator:
for i, each in enumerate(element):
#print(i, last[i], each)
if last[i] != each:
return False
else:
return True
This function can compare as many lists you want with equal length. Just call cmp(list1, list2, list3)
This code will produce list of elements which is consist in both a and b list
a = [1,2,3,4]
b = [2,3,1,7]
c = [e for e in a if e in b]
It might be complex by memory in case if you use big arrays but if you plan to use this data than why not

How do I access the 1st element of each list in a lists of lists

Example:
numbers = ['1','2','3']
letters = ['a','b','c']
I want to get [1,a] as a results. Yeah I can loop through it, but I'm wondering if there is a fast one line way of doing this.
EDIT EDIT !!!!
I made a horrible mistake in describing the problem.
I have access to the combined list (the list of lists of the question):
list_of_lists = [ numbers, letters]
which is equal to:
[ ['1','2','3'],['a','b','c']]
Sorry for the confusion. The end result is still the same, this would be ['1','a'].
Try a list comprehension:
# (numbers, letters) can be replaced with `list_of_lists`
>>> [ x[0] for x in (numbers, letters) ]
['1', 'a']
import operator
map(operator.itemgetter(0), [numbers, letters])
list_of_lists = [['1', '2', '3'], ['a', 'b', 'c']]
list_of_firsts = [l[0] for l in list_of_lists]
You may be looking for zip
I would try:
zip(*list_of_lists)[0]

Filter array to show rows with a specific value in a specific column

Let's say i have a multidimensional list l:
l = [['a', 1],['b', 2],['c', 3],['a', 4]]
and I want to return another list consisting only of the rows that has 'a' in their first list element:
m = [['a', 1],['a', 4]]
What's a good and efficient way of doing this?
Definitely a case for a list comprehension:
m = [row for row in l if 'a' in row[0]]
Here I'm taking your "having 'a' in the first element" literally, whence the use of the in operator. If you want to restrict this to "having 'a' as the first element" (a very different thing from what you actually wrote!-), then
m = [row for row in l if 'a' == row[0]]
is more like it;-).
m = [i for i in l if i[0] == 'a']
With the filter function:
m = filter(lambda x: x[0] == 'a', l)
or as a list comprehension:
m = [x for x in l where x[0] == 'a']
What's wrong with just:
m = [i for i in l if i[0] == 'a']
Or:
m = filter(lambda x: x[0] == 'a', l)
I doubt the difference between these will be significant performance-wise. Use whichever is most convenient. I don't like lambdas, but the filter can be replaced with itertools.ifilter for larger lists if that's a problem, but you can also change the list comprehension to a generator (change the [] to ()) to achieve the same general result. Other than that, they're probably identical.
[i for i in l if i[0]=='a']
btw, take a look at Python's list comprehension with conditions.

Categories

Resources