Selecting 1st element of every list within list - python

I have the following list of lists with multiple elements:
list = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
I want to populate a new_list1 and new_list2 with the first and second numbers within each of those lists, respectively, yielding:
new_list1 = [1633425661439,
1633428739018,
1633432086311]
And:
new_list2 = [0.11643042583898743,
0.11682454707026001,
0.11950356856187618]
I tried:
for n in list:
for i in n:
new_list1.append(i[0])
new_list2.append(i[1])
But got: TypeError: 'int' object is not subscriptable

You can try something
list_ = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
list_a = [first[0] for first in list_]
list_b = [first[1] for first in list_]
Other way
new_list1 = []
new_list2 = []
for inner_list in list_:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])

You can transpose it like this:
lst = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
new_list_1, new_list_2 = map(list, zip(*lst))
And if you are ok with tuples instead of lists, the following will do:
new_list_1, new_list_2 = zip(*lst)
And you really should not name a variable list. It shadows the built-in type.
You can also use simple comprehensions:
new_list_1 = [a for a, _ in lst]
new_list_2 = [a for _, a in lst]
Some docs:
map
zip

You have one level of nesting too much, this would
for n in list:
for i in n:
print(i)
would print single elements, which are numbers, you need to do
for n in list:
new_list1.append(n[0])
new_list2.append(n[1])
As side note, please avoid using list as it is already used name in python. Overshadowing it might cause unexpected behavior, you can use lst name i.e.:
lst = [[1,2],[3,4],[5,6]]
new_lst1 = []
new_lst2 = []
for n in lst:
new_lst1.append(n[0])
new_lst2.append(n[1])
print(new_lst1)
print(new_lst2)
output
[1, 3, 5]
[2, 4, 6]

you can unpack the first and second number in the for loop itself.
(BTW best not call the variable "list" because it is the same as a python build-in)
list_ = [[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
new_list1 = []
new_list2 = []
for (i, j) in l:
new_list1.append(i)
new_list2.append(j)

Following PEP-8 code style guideline please do not name the variables with reserved keywords like list, dict, for, etc.
With the second loop you iterate over int numbers within the inner lists.
If you need to use only the first 2 elements of each list, one loop os enough:
list_ = [
[1633425661439, 0.11643042583898743],
[1633428739018, 0.11682454707026001],
[1633432086311, 0.11950356856187618]]
for inner_list in list_:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])

list= [[1633425661439, 0.11643042583898743], [1633428739018, 0.11682454707026001], [1633432086311, 0.11950356856187618]]
new_list1 = [ ]
new_list2 = [ ]
for inner_list in list:
new_list1.append(inner_list[0])
new_list2.append(inner_list[1])
print(new_list1)
print(new_list2)

Related

List combination based on value of each index in another list

I have the following two lists
list_1 = [3, 5, 7, 2]
list_2 = [
'1-CHA', '2-NOF', '3-INC',
'4-CHA', '5-NOF', '6-NOF', '7-INC', '8-INC',
'9-INC', '10-INC', '11-CHA', '12-NOF', '13-CHA', '14-CHA', '15-INC',
'16-INC', '17-INC'
]
I want to combine the two lists in the following way:
final_list = [
'1-CHA|2-NOF|3-INC',
'4-CHA|5-NOF|6-NOF|7-INC|8-INC',
'9-INC|10-INC|11-CHA|12-NOF|13-CHA|14-CHA|15-INC',
'16-INC|17-INC'
]
final_list - should have the same length as list_1
You can create an iterator from list_2 so that you can fetch items from the list for the number of times specified in list_1 by calling next on the iterator:
seq = iter(list_2)
final_list = ['|'.join(next(seq) for _ in range(n)) for n in list_1]
You can also use itertools.islice instead to avoid repeated calls to next (thanks to #gog for the suggestion):
from itertools import islice
seq = iter(list_2)
final_list = ['|'.join(islice(seq, 0, n)) for n in list_1]
To do it without using list comprehension or generator expression, you can create an empty list and append items to it:
seq = iter(list_2)
final_list = []
for n in list_1:
items = []
for _ in range(n):
items.append(next(seq))
final_list.append('|'.join(items))
Demo: https://replit.com/#blhsing/BlandEssentialJavadoc
You could do it like this:
final_list = [
# Join with a `|` pipe character
'|'.join(
# Slice list 2
list_2[
# Start at the sum of values less than i then sum of values including i
sum(list_1[:i]):sum(list_1[:i+1])])
for i in range(len(list_1))
]
On one line:
final_list = ['|'.join(list_2[sum(list_1[:i]):sum(list_1[:i+1])]) for i in range(len(list_1))]

Splitting a list into single list amounts

I'm trying to split a list in python to single amounts but I can't seem to get it to work and I can't find any questions on stackoverflow which try to achieve this
At the moment, I've got code which is producing id's but I need those id's separate
['325', '323', '324', '322']
I want to split these so they go into
['323']
['324']
['322']
What would be the best way to do this?
The list has different amounts and some of them only have one id
since you want each element of the list in a separate/individual list, then you have to iterate through the original list and add an element in a empty list and append that new list to the resultant list.
main_list = ['325', '323', '324', '322']
final_solution = []
for element in main_list:
tmp = [element]
final_solution.append(tmp)
print(final_solution)
# output -> [['325'], ['323'], ['324'], ['322']]`
or, by using list comprehension
final_solution = [[element] for element in main_list]
print(final_solution)
# output -> [['325'], ['323'], ['324'], ['322']]`
Here's a simple one-liner that turns each item in the list to an array containing the item:
list(map(lambda x : [x], arr))
so if you have arr = [1,2,3] :
>>> a = list(map(lambda x : [x], arr))
>>> print(a)
[[1], [2], [3]]
my_list = ['325', '323', ['324', '327'], '345', '322']
new_list = []
for i in my_list:
if type(i) == str:
new_list.append([i])
else:
for j in i:
new_list.append([j])
new_list = [['325'], ['323'], ['324'], ['327'], ['345'], ['322']].

List resolver with tuples

I have a list:
List = [('4022-a751',), ('0bfc-4d53',)]
And want to resolve it into the output below:
Output = ['4022-a751','0bfc-4d53']
You should read about List Comprehensions in Python
list_ = [('4022-a751',), ('0bfc-4d53',)]
res = [x for item in list_ for x in item]
Output
['4022-a751', '0bfc-4d53']
A tuple can be manipulated like an array with index.
input_arr = [('4022-a751',), ('0bfc-4d53',)]
output_arr = [a[0] for a in input_arr]
print(output_arr)
You can use this.
old_list= [('4022-a751',), ('0bfc-4d53',)]
new_list = [''.join(i) for i in old_list]
print(new_list)

How to merge n lists together item by item for each list

I want to make one large list for entering into a database with values from 4 different lists. I want it to be like
[[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]], etc.....]
Another issue is that currently the data is received like this:
[ [ [list1[0], list1[1], [list1[3]]], [[list2[0]]], etc.....]
I've tried looping through each list using indexs and adding them to a new list based on those but it hasn't worked, I'm pretty sure it didn't work because some of the lists are different lengths (they're not meant to be but it's automated data so sometimes there's a mistake).
Anyone know what's the best way to go about this? Thanks.
First list can be constructed using zip function as follows (for 4 lists):
list1 = [1,2,3,4]
list2 = [5,6,7,8]
list3 = [9,10,11,12]
list4 = [13,14,15,16]
res = list(zip(list1,list2,list3,list4))
For arbitrtary number of lists stored in another list u can use *-notation to unpack outer list:
lists = [...]
res = list(zip(*lists))
To construct list of lists for zipping from you data in second issue use flatten concept to it and then zip:
def flatten(l):
res = []
for el in l:
if(isinstance(el, list)):
res += flatten(el)
else:
res.append(el)
return res
auto_data = [...]
res = list(zip(*[flatten(el) for el in auto_data]))
Some clarification at the end:
zip function construct results of the smallest length between all inputs, then you need to extend data in list comprehension in last code string to be one length to not lose some info.
So if I understand correctly, this is your input:
l = [[1.1,1.2,1.3,1.4],[2.1,2.2,2.3,2.4],[3.1,3.2,3.3,3.4],[4.1,4.2,4.3,4.4]]
and you would like to have this output
[[1.1,2.1,3.1,4.1],...]
If so, this could be done by using zip
zip(*l)
Make a for loop which only gives you the counter variable. Use that variable to index the lists. Make a temporary list , fill it up with the values from the other lists. Add that list to the final one. With this you will et the desired structure.
nestedlist = []
for counter in range(0,x):
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
If all the 4 lists are the same length you can use this code to make it even nicer.
nestedlist = []
for counter in range(0,len(firstlist)): #changed line
temporarylist = []
temporarylist.append(firstlist[counter])
temporarylist.append(secondlist[counter])
temporarylist.append(thirdlist[counter])
temporarylist.append(fourthlist[counter])
nestedlist.append(temporarylist)
This comprehension should work, with a little help from zip:
mylist = [i for i in zip(list1, list2, list3, list4)]
But this assumes all the list are of the same length. If that's not the case (or you're not sure of that), you can "pad" them first, to be of same length.
def padlist(some_list, desired_length, pad_with):
while len(some_list) < desired_length:
some_list.append(pad_with)
return some_list
list_of_lists = [list1, list2, list3, list4]
maxlength = len(max(list_of_lists, key=len))
list_of_lists = [padlist(l, maxlength, 0) for l in list_of_lists]
And now do the above comprehension statement, works well in my testing of it
mylist = [i for i in zip(*list_of_lists)]
If the flatten concept doesn't work, try this out:
import numpy as np
myArray = np.array([[list1[0], list2[0], list3[0], list4[0]], [list1[1], list2[1], list3[1], list4[1]]])
np.hstack(myArray)
Also that one should work:
np.concatenate(myArray, axis=1)
Just for those who will search for the solution of this problem when lists are of the same length:
def flatten(lists):
results = []
for numbers in lists:
for output in numbers:
results.append(output)
return results
print(flatten(n))

Finding indices of items from a list in another list even if they repeat

This answer works very well for finding indices of items from a list in another list, but the problem with it is, it only gives them once. However, I would like my list of indices to have the same length as the searched for list.
Here is an example:
thelist = ['A','B','C','D','E'] # the list whose indices I want
Mylist = ['B','C','B','E'] # my list of values that I am searching in the other list
ilist = [i for i, x in enumerate(thelist) if any(thing in x for thing in Mylist)]
With this solution, ilist = [1,2,4] but what I want is ilist = [1,2,1,4] so that len(ilist) = len(Mylist). It leaves out the index that has already been found, but if my items repeat in the list, it will not give me the duplicates.
thelist = ['A','B','C','D','E']
Mylist = ['B','C','B','E']
ilist = [thelist.index(x) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
Basically, "for each element of Mylist, get its position in thelist."
This assumes that every element in Mylist exists in thelist. If the element occurs in thelist more than once, it takes the first location.
UPDATE
For substrings:
thelist = ['A','boB','C','D','E']
Mylist = ['B','C','B','E']
ilist = [next(i for i, y in enumerate(thelist) if x in y) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
UPDATE 2
Here's a version that does substrings in the other direction using the example in the comments below:
thelist = ['A','B','C','D','E']
Mylist = ['Boo','Cup','Bee','Eerr','Cool','Aah']
ilist = [next(i for i, y in enumerate(thelist) if y in x) for x in Mylist]
print(ilist) # [1, 2, 1, 4, 2, 0]
Below code would work
ilist = [ theList.index(i) for i in MyList ]
Make a reverse lookup from strings to indices:
string_indices = {c: i for i, c in enumerate(thelist)}
ilist = [string_indices[c] for c in Mylist]
This avoids the quadratic behaviour of repeated .index() lookups.
If you data can be implicitly converted to ndarray, as your example implies, you could use numpy_indexed (disclaimer: I am its author), to perform this kind of operation in an efficient (fully vectorized and NlogN) manner.
import numpy_indexed as npi
ilist = npi.indices(thelist, Mylist)
npi.indices is essentially the array-generalization of list.index. Also, it has a kwarg to give you control over how to deal with missing values and such.

Categories