I have a list of data:
data_list = [[1,2,3], [4,5,6], [7,8,9], ...]
I am trying to assign each element to a separate list so that:
Bin1 = [1,2,3]
Bin2 = [4,5,6]
....
Bin100 = [..,..,..]
I'm not sure how to do this without doing the manual way of initializing lists 1 by 1. Tried searching for a function how to go about it but have not found anything.
Once I have the lists initialized, I'd need to append the data from data_list:
for i in range(0, len(data_list)):
bin1.append(data_list[i][1])
bin2.append(data_list[i][2])
.......
Again, a shortcut way of doing this would be so useful!
You could use a dictionary if you wanted to access the lists with a key like "Bin1":
data_list = [[1,2,3], [4,5,6], [7,8,9]]
d = {}
for i, v in enumerate(data_list, 1):
d['Bin{}'.format(i)] = v
print(d) # >>> {'Bin1': [1, 2, 3], 'Bin3': [7, 8, 9], 'Bin2': [4, 5, 6]}
print(d['Bin1']) # >>> [1, 2, 3]
Or using a dict comprehension:
d = {'Bin{}'.format(i): v for i,v in enumerate(data_list, 1)}
you can simply write below code
l = [ [i,i+1,i+2] for i in range(1,YOUR_MAX_LENGTH,3) ]
hope this helps
Use dictionary comprehension to make a dictionary of lists, note this makes copies:
data_list = [[1,2,3], [4,5,6], [7,8,9]]
# To make copies
separate_lists = {'bin'+str(i): sublist
for i,sublist in enumerate(data_list,1)}
print (separate_lists)
To make a dictionary without making copies, this should work:
# To remove sublists from data_list and put them in the dictionary
separate_lists_not_copied = {}
for i in range(1,len(data_list)+1):
separate_lists_not_copied['bin'+str(i)] = data_list.pop(0)
print (separate_lists_not_copied)
Both print:
{'bin3': [7, 8, 9], 'bin1': [1, 2, 3], 'bin2': [4, 5, 6]}
use locals() to create variable name on-the-fly and iterate over all your sublists.
For those who are not aware of this function:
Update and return a dictionary representing the current local symbol table.
Free variables are returned by locals() when it is called in function
blocks, but not in class blocks.
data_list = [[1,2,3], [4,5,6], [7,8,9]]
for i, sublist in enumerate(data_list, 1):
locals()['bin_{}'.format(i)] = sublist
print bin_1 # [1, 2, 3]
print bin_3 # [7,8,9]
NOTE: Don't use uppercase on variable name since it is use by convention on for python classes. so bin_1 is a better name than Bin1
Related
I have a tuple where my_tuple[0] contains an integer and my_tuple[1] contains 3 lists. So
my_tuple[0]=11
my_tuple[1]= [[1,2,3], [4,5,6], [7,8,9]]
for tuple_item in my_tuple[1]:
print tuple_item
How could I extract the lists from my_tuple[1] without using any external libraries (my current python interpreter has limitations)? I would like to be take the lists from the tuple and then create a dict of lists. Alternatively, I could do a list of lists
key=my_tuple[0]
#using the same key
my_dict[key]= list1
my_dict[key]= list2
my_dict[key]= list3
#or
for tuple_item in my_tuple[1]:
list_of_lists.append(tuple_item)
You need to generate a key for each list. In this example, I use the index of each list:
my_tuple = [None, None] # you need a list, otherwise you cannot assign values: mytuple = (None, None) is a tuple
my_tuple[0] = 11
my_tuple[1] = [[1,2,3], [4,5,6], [7,8,9]]
dict_of_lists = dict()
for i, tuple_item in enumerate(my_tuple[1]):
key = str(i) # i = 0, 1, 2; keys should be strings
dict_of_lists[key] = tuple_item
dict_of_lists
>> {'0': [1, 2, 3], '1': [4, 5, 6], '2': [7, 8, 9]}
Based on your comment in response to #Gijs, it sounds like you've got a perfectly good data structure already. Nonetheless, here's another:
#python3
from collections import namedtuple
Point = namedtuple("Point", "x, y, z")
Triangle = namedtuple("Triangle", "number, v1, v2, v3")
# Here is your old format:
my_tuple = (11, [ [1,2,3], [4,5,6], [7,8,9] ])
v1 = Point(*my_tuple[1][0])
v2 = Point(*my_tuple[1][1])
v3 = Point(*my_tuple[1][2])
num = my_tuple[0]
new_triangle = Triangle(num, v1, v2, v3)
print(new_triangle)
Output is:
Triangle(number=11, v1=Point(x=1, y=2, z=3), v2=Point(x=4, y=5, z=6), v3=Point(x=7, y=8, z=9))
You can use new_triangle.num and new_triangle.v1 to access members, and you can use new_triangle.v3.z to access submembers.
But I'll bet it won't be long before you wish you could loop over the vertices...
Say for example:
list = { [1,2,3],[4,5,6],[3,4],[2,7,8,9] }
is there a way in python to remove a sublist and make sure that other sublists index's remain the same. So for example if i was to remove the sublist [3,4], could i make sure that the index of [2,7,8,9] remains as 3 in this case? if this is possible it would really be helpful! thanks!
Maybe. It depends on how you use the list and just how "listy" the resulting object needs to be.
l = [ [1,2,3],[4,5,6],[3,4],[2,7,8,9] ]
You could replace the sublist with something else like a None. Then your code would have to know to ignore None when it processes the list.
print(l[3])
l[2] = None
print(l[3])
or you could convert the list to a dict and delete the member. You can still index the object but since its now a dict, your code will have to treat it like a dict.
l = dict(enumerate(l))
print l[3]
del l[2]
print l[3]
These tricks will only work in some specialized environments.
You can just delete the elements in [3,4] and keep the empty sub-list.
>>> lst = [[1,2,3],[4,5,6],[3,4],[2,7,8,9]]
>>> del lst[2][:]
>>> lst
[[1, 2, 3], [4, 5, 6], [], [2, 7, 8, 9]]
Please note that you should not use list as a variable name as list is a built in function
But you can store the index with the value as a tuple. First make a modified list which has both index and value. Then you are free to remove any of the element.
lst = [[1,2,3],[4,5,6],[3,4],[2,7,8,9]]
modified = list(enumerate(lst))
To explain a bit:
modified=[]
for i,v in enumerate(lst):
modified.append((i,v))
print modified
Output:
[(0, [1, 2, 3]), (1, [4, 5, 6]), (2, [3, 4]), (3, [2, 7, 8, 9])]
given à list of lists:
L = [[1,2,3], [3,4,5], [1,2,3]]
how to get a list where each list is unique:
L = [[1,2,3], [3,4,5]]
thanks
If you don't care about the order of sub-lists:
In [11]: list(map(list, set(map(tuple, L))))
Out[11]: [[3, 4, 5], [1, 2, 3]]
Better yet, you should probably just move to using sets of tuples as your data structure.
Bit of jinking around but how about this?
[list(el) for el in set(tuple(el) for el in L)]
It works because lists can't be compared to one another but tuples can. The error message gives it away if you try to directly make a set from a list of lists:
unhashable type: 'list'
L = [[1,2,3], [3,4,5], [1,2,3]]
newlist = []
for item in L:
if item not in newlist:
newlist.append(item)
You can convert to a set of tuples and then back to a list.
L = [[1,2,3], [3,4,5], [1,2,3]]
setL = set(tuple(i) for i in L)
newL = list(list(i) for i in setL)
print newL
[[3, 4, 5], [1, 2, 3]]
If I have a list:
my_list = [3,2,2,3,4,1,3,4]
and a tuple
my_tuple = (3,5)
What's the best way of replacing elements in my_list using the tuple:
result = [5,2,2,5,4,1,5,4]
e.g.
for item in my_list:
if(item == my_tuple[0]):
item = my_tuple[1]
More generally, I would have a list of lists, and a list of tuples, and I would like to apply each of the tuples to each of the lists within the list of lists.
The more natural data structure for my_tuple is a dictionary. Consider something like this and use the .get() method:
>>> my_lists = [[3,2,2,3,4,1,3,4], [1,2,3,4,5,6]]
>>> my_tuple_list = [(3,5), (6, 7)]
>>> my_dict = dict(my_tuple_list)
>>> my_dict
{3: 5, 6: 7}
>>> my_lists = [[my_dict.get(x,x) for x in somelist] for somelist in my_lists]
>>> my_lists
[[5, 2, 2, 5, 4, 1, 5, 4], [1, 2, 5, 4, 5, 7]]
Per #Wooble's comment, your code will work if you enumerate.
list_of_lists = [[3,2,2,3,4,1,3,4], [1,3,5,3,4,6,3]]
list_of_tuples = [(3,5), (1,9)]
def tup_replace(mylist, mytuple):
for i, item in enumerate(mylist):
if item == mytuple[0]:
mylist[i] = mytuple[1]
return mylist
then you can just nest that some more to work on a list of list and list of tuples.
for mylist in list_of_lists:
for mytuple in list_of_tuples:
mylist = tup_replace(mylist, mytuple)
print mylist
That said, the dictionary approach is probably better.
Using if item == my_tuple[0], ... in a general case sounds like you are making a switch statement that you want to apply to each item in your list. Use a dictionary instead if you can. (Why isn't there a switch or case statement in python?)
Convert your list of tuples to a lookup dictionary (python's switch statement):
replacements = dict(my_tuples) #thanks to #julio
Then for a single list, reproduce the list with a comprehension, but replace each value with the new value from replacements if it exists:
replaced_list = [replacements.get(original,original) for original in my_list]
I guess there is a more efficient way to do it, but that's for a single list with a list of tuples. You say you also need to do it for a list of lists? Just nest that?
Could you explain more about where you are getting this data and why you need to do it?
If you are trying to replace every 3 in your list with 5, this will do:
[x == my_tuple[0] and my_tuple[1] or x for x in my_list]
If you want to do this, with more than one "translational" tuple, then I really suggest to use a dictionary instead:
trans = {3: 5, 4: 6}
[trans.get(x,x) for x in my_list]
And in the more general case where you have more than one list:
ll = [[3, 2, 3, 4], [5, 4, 3, 4]]
trans = {3: 5, 4: 6}
for i in range(len(ll)):
ll[i] = [trans.get(x,x) for x in ll[i]]
Supposing that you want to replace every old list in ll with the new one.
Possible Duplicate:
How can I turn a list into an array in python?
How can I turn a list such as:
data_list = [0,1,2,3,4,5,6,7,8]
into a list of lists such as:
new_list = [ [0,1,2] , [3,4,5] , [6,7,8] ]
ie I want to group ordered elements in a list and keep them in an ordered list. How can I do this?
Thanks
This groups each 3 elements in the order they appear:
new_list = [data_list[i:i+3] for i in range(0, len(data_list), 3)]
Give us a better example if it is not what you want.
This assumes that data_list has a length that is a multiple of three
i=0
new_list=[]
while i<len(data_list):
new_list.append(data_list[i:i+3])
i+=3
Something like:
map (lambda x: data_list[3*x:(x+1)*3], range (3))
Based on the answer from Fred Foo, if you're already using numpy, you may use reshape to get a 2d array without copying the data:
import numpy
new_list = numpy.array(data_list).reshape(-1, 3)
new_list = [data_list[x:x+3] for x in range(0, len(data_list) - 2, 3)]
List comprehensions for the win :)
The following function expands the original context to include any desired list of lists structure:
def gen_list_of_lists(original_list, new_structure):
assert len(original_list) == sum(new_structure), \
"The number of elements in the original list and desired structure don't match"
list_of_lists = [[original_list[i + sum(new_structure[:j])] for i in range(new_structure[j])] \
for j in range(len(new_structure))]
return list_of_lists
Using the above:
data_list = [0,1,2,3,4,5,6,7,8]
new_list = gen_list_of_lists(original_list=data_list, new_structure=[3,3,3])
# The original desired outcome of [[0,1,2], [3,4,5], [6,7,8]]
new_list = gen_list_of_lists(original_list=data_list, new_structure=[2,3,3,1])
# [[0, 1], [2, 3, 4], [5, 6, 7], [8]]
The below one is more optimized and quite straightforward.
data_list = [0,1,2,3,4,5,6,7,8]
result =[]
i=0
while i <(len(data_list)-2):
result.append(data_list[i:i+3])
i+=3
print(result)
**output**
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Here is a generalized solution
import math
data_list = [0,1,2,3,4,5,6,7,8]
batch_size=3
n_batches=math.ceil(len(data_list)/batch_size)
[data_list[x*batch_size:min(x*batch_size+batch_size,len(data_list))]
for x in range(n_batches)]
It works even if the last sublist is not the same size as the rest (<batch_size)
Do you have any sort of selection criteria from your original list?
Python does allow you to do this:
new_list = []
new_list.append(data_list[:3])
new_list.append(data_list[3:6])
new_list.append(data_list[6:])
print new_list
# Output: [ [0,1,2] , [3,4,5] , [6,7,8] ]