Merging lists horizontally into a new list - python

Python newbie here struggling with numpy.
I have 18 lists
L1 = [1,2,3,4]
L2 = [5,6,7,8]
L3 = [5,7,8,5]
..........
......
L18 = [6,4,7,8]
I want to merge them into a new list (lets say L_ALL), so that in a single row I have all the lists..(1 row, 18 columns with lists...)
I have tried
L_ALL = [L1,L2,....L18]
but this merges them adding new rows, so I end up with a list with 18 rows.
Things like hstack, np.concatenate and sum do not help because they do something like:
L_ALL = [1,2,3,4,5,6,7,8,5,7....]
and I need the lists as separate lists in different columns (same row), not a single list (column) with all the elements.
Does this makes sense?
Thanks in advance

import pandas as pd
L1 = [1,2,3,4]
L2 = [5,6,7,8]
L3 = [5,7,8,5]
l_all = [[L1,L2,L3]]
df = pd.DataFrame(l_all)
this creates a single row with as many columns as you have the list
Now if you do
df.values[0]
you get
array([list([1, 2, 3, 4]), list([5, 6, 7, 8]), list([5, 7, 8, 5])],
dtype=object)

You can try in this way
L1 = [1,2,3,4]
L2 = [5,6,7,8]
L3 = [5,7,8,5]
..........
......
L18 = [6,4,7,8]
finalList=['']
finalList.append(L1)
finalList.append(L2)
.
.
.
finalList.append(L18)
print(" ".join(map(str, finalList)))
You will get output as follows
[1, 2, 3, 4] [5, 6, 7, 8] [5,7,8,5] ... [6,4,7,8]

Related

Python produce alternative numbers list from a list of n numbers

I have a list of n numbers. I want to group them in g groups. Also, I want to reverse elements in every odd group. Finally, I would combine all elements in even and odd groups into a new sublist. First I am giving what answer I am expecting and where I went wrong:
Expected answer:
num = 14
grp = 4
# A list of num natural numbers arranged in group (row) of 4 numbers
lst =
[0,1,2,3,
4,5,6,7,
8,9,10,11,
12,13]
lst =
[[0,1,2,3],
[4,5,6,7],
[8,9,10,11],
[12,13]]
# Reverse elements in odd rows
newlst =
[[0,1,2,3],
[7,6,5,4], # reversed here
[8,9,10,11],
[13,12]] # reversed here
# combine elements in all sublists by their position
# combine first element in all sublists into a new sublist
sollst =
[[0,7,8,13],[1,6,9,12],[2,5,10],[3,4,11]]
My solution:
num = 14
grp = 4
#### print
lst= list(range(0,num,1))
newlst= [lst[i:i+grp:1] for i in range(0,num,grp)]
evnlst = newlst[0::2]
oddlst = newlst[1::2]
newoddlst = [oddlst [i][::-1] for i in range(len(oddlst))]
sollst= evnlst + newoddlst
# This gives [[0, 1, 2, 3], [8, 9, 10, 11], [7, 6, 5, 4], [13, 12]]
from itertools import zip_longest
print([[x for x in t if x is not None] for t in zip_longest(fevngps)])
Present answer:
I reached the one step before the final answer and now I have to combine the lists of different lengths and I am running into an error
TypeError: 'int' object is not subscriptable
One approach:
from itertools import zip_longest
num = 14
grp = 4
lst = list(range(0, num, 1))
newlst = [lst[i:i + grp:1] for i in range(0, num, grp)]
# build new list where the sub-list are reversed if in odd indices
revlst = [lst[::-1] if i % 2 == 1 else lst for i, lst in enumerate(newlst)]
# zip using zip_longest and filter out the None values (the default fill value of zip_longest)
result = [[v for v in vs if v is not None] for vs in zip_longest(*revlst)]
print(result)
Output
[[0, 7, 8, 13], [1, 6, 9, 12], [2, 5, 10], [3, 4, 11]]

Comparisons between an arbitrary number of lists of arbitrary length Python

Given an arbitrary number of lists of integers of arbitrary length, I would like to group the integers into new lists based on a given distance threshold.
Input:
l1 = [1, 3]
l2 = [2, 4, 6, 10]
l3 = [12, 13, 15]
threshold = 2
Output:
[1, 2, 3, 4, 6] # group 1
[10, 12, 13, 15] # group 2
The elements of the groups act as a growing chain so first we have
abs(l1[0] - l2[0]) < threshold #true
so l1[0] and l2[0] are in group 1, and then the next check could be
abs(group[-1] - l1[1]) < threshold #true
so now l1[1] is added to group 1
Is there a clever way to do this without first grouping l1 and l2 and then grouping l3 with that output?
Based on the way that you asked the question, it sounds like you just want a basic python solution for utility, so I'll give you a simple solution.
Instead of treating the lists as all separate entities, it's easiest to just utilize a big cluster of non-duplicate numbers. You can exploit the set property of only containing unique values to go ahead and cluster all of the lists together:
# Throws all contents of lists into a set, converts it back to list, and sorts
elems = sorted(list({*l1, *l2, *l3}))
# elems = [1, 2, 3, 4, 6, 10, 12, 13, 15]
If you had a list of lists that you wanted to perform this on:
lists = [l1, l2, l3]
elems = []
[elems.extend(l) for l in lists]
elems = sorted(list(set(elems)))
# elems = [1, 2, 3, 4, 6, 10, 12, 13, 15]
If you want to keep duplicated:
elems = sorted([*l1, *l2, *l3])
# and respectively
elems = sorted(elems)
From there, you can just do the separation iteratively. Specifically:
Go through the elements one-by-one. If the next element is validly spaced, add it to the list you're building on.
When an invalidly-spaced element is encountered, create a new list containing that element, and start appending to the new list instead.
This can be done as follows (note, -1'th index refers to last element):
out = [[elems[0]]]
thresh = 2
for el in elems[1:]:
if el - out[-1][-1] <= thresh:
out[-1].append(el)
else:
out.append([el])
# out = [[1, 2, 3, 4, 6], [10, 12, 13, 15]]

Getting unique values in python using List Comprehension technique

I want to get the values that appear in one of the lists but not in the others. I even tried using '<>', it says invalid syntax. I am trying using list comprehensions.
com_list = []
a1 = [1,2,3,4,5]
b1 = [6,4,2,1]
come_list = [a for a in a1 for b in b1 if a != b ]
Output:
[1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5]
My expected output would be `[3, 5, 6]
What you want is called symmetric difference, you can do:
a1 = [1,2,3,4,5]
b1 = [6,4,2,1]
set(a1).symmetric_difference(b1)
# {3, 5, 6}
which you can also write as:
set(a1) ^ set(b1)
If you really want a list in the end, just convert it:
list(set(a1) ^ set(b1))
# [3, 5, 6]
a1 = [1,2,3,4,5]
b1 = [6,4,2,1]
If you really want to do that using list comprehensions, well, here it is, but it's really not the right thing to do here.
A totally inefficient version:
# Don't do that !
sym_diff = [x for x in a1+b1 if x in a1 and x not in b1 or x in b1 and x not in a1]
print(sym_diff)
# [3, 5, 6]
It would be a bit better using sets to test membership efficiently:
# Don't do that either
a1 = set([1,2,3,4,5])
b1 = set([6,4,2,1])
sym_diff = [x for x in a1|b1 if x in a1 and x not in b1 or x in b1 and x not in a1]
print(sym_diff)
# [3, 5, 6]
But if you start using sets, which is the right thing to do here, use them all the way properly and use symmetric_difference.
You can do
come_list =[i for i in list((set(a1) - set(b1))) + list((set(b1) - set(a1)))]
print(come_list)
Output
[3, 5, 6]
This new list contains all unique numbers for both of the lists together.
the problem with this line come_list = [a for a in a1 for b in b1 if a != b ] is that the items iterating over each item in the first list over all the items in the second list to check if it's inited but it's not giving unique numbers between both.

Add an unknown number of lists by index

I need to add every index of an unknown amount of lists together into one list.
An example of what I mean:
list_a = [1,2,3,4,5]
list_b = [2,4,6,8,10]
list_c = [3,6,9,12,15]
def sum_lists():
temp_list = []
for index in range(len(list_a)):
temp_list.append(list_a[index] + list_b[index] + list_c[index])
return temp_list
total = sum_lists()
The expected output of my example code would be:
total = [6,12,18,24,30]
How would I accomplish the summation of an unknown amount of lists, for example 20 lists? I won't have to do this addition over thousands of lists, but I wouldn't know how many lists I have to add initially.
Any help would be greatly appreciated. All of the lists will be of the same length.
Create a list of lists:
In [124]: big_list = [list_a, list_b, list_c]
Now, zip em up and apply sum to each one using map:
In [125]: list(map(sum, zip(*big_list)))
Out[125]: [6, 12, 18, 24, 30]
You have other alternatives to map. For example, using a list comprehension:
In [126]: [sum(x) for x in zip(*big_list)]
Out[126]: [6, 12, 18, 24, 30]
You can store lists in lists and sum over them.
You could have something like this:
list_a = [1,2,3,4,5]
list_b = [2,4,6,8,10]
list_c = [3,6,9,12,15]
list_of_lists = [list_a, list_b, list_c] # this could be 20+ lists
def sum_lists():
temp_list = []
for index in range(len(list_a)):
temp_list.append(sum([l[index] for l in list_of_lists]))
return temp_list
total = sum_lists()
Here's my alternative:
list_a = [1, 2, 3, 4, 5]
list_b = [2, 4, 6, 8, 10]
list_c = [3, 6, 9, 12, 15]
def sum_lists(*arg):
return [sum(i) for i in zip(*arg)]
results = sum_lists(list_a, list_b, list_c)

Giving indices to list entries

I have a Python list looking like this:
A1 = ['a','a','a','foo','c','d','a','e','bar','bar','bar','e','d','d']
I want to transform it into this...
A2 = [1,1,1,2,3,4,1,5,6,6,6,5,4,4]
...where entries in A1 are taken in order and given an incremental index in A2.
Is there a straight forward way to do this in Python?
index_map = {}
result = []
i = 0 # or 1 or whatever
for value in A1:
if value not in index_map:
index_map[value] = i
i = i + 1
result.append(index_map[value])
One of the ways of doing it can be.
>>> A1 = ['a','a','a','foo','c','d','a','e','bar','bar','bar','e','d','d']
>>> ref = []
>>> for i in A1:
... if i not in ref:
... ref.append(i)
...
>>> [ref.index(i)+1 for i in A1]
[1, 1, 1, 2, 3, 4, 1, 5, 6, 6, 6, 5, 4, 4]
Logic
We remove the duplicate values in the original list (whilst preserving order). Then we find the index of the individual items in the list with respect to the original list.
Advantages
Simple concepts/ Beginner level
Very much straight forward.
Disadvantages
Slow as it is of the order O(n2)
Use collections.defaultdict and itertools.count to create a dictionary that produces unique ids on demand for each new key:
>>> unique_ids = collections.defaultdict(itertools.count(start=1).next)
>>> [unique_ids[item] for item in A1]
[1, 1, 1, 2, 3, 4, 1, 5, 6, 6, 6, 5, 4, 4]
Though similar to Bhargav Rao's answer, this may be faster for longer arrays (especially with high numbers of unique elements) given its use of hashing.
A1 = ['a','a','a','foo','c','d','a','e','bar','bar','bar','e','d','d']
uniqueEntries = 0
ref = {}
A2 = []
for x in A1:
if x not in ref:
uniqueEntries += 1
ref[x] = uniqueEntries
A2.append(ref[x])
This could hurt your eyes but it works, just use sets:
[list(set(your_list)).index(x) for x in your_list]

Categories