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.
Related
I have following objects
a = ("one", 1)
b = ("two", 2)
c = ("seven", 7)
my_dict = {10: a, 20:b, 70:c}
I want to get a list of [1, 2, 7] from my_dict. Whats the most pythonic way to do so?
Just use list comprehension. It's the most pythonic way of doing most things ;)
output = [x[1] for x in my_dict.values()]
If you like the functional way, you could use:
list(zip(*my_dict.values()))[1]
Output: (1, 2, 7)
Or, as list:
list(list(zip(*my_dict.values()))[1])
Output: [1, 2, 7]
You can use tuple unpacking inside the list comprehension to avoid having to index into the tuple:
result = [item for _, item in my_dict.values()]
print(result)
This prints:
[1, 2, 7]
What is the most pythonic way to remove all lists in a list?
For example, if there is a list like this [1,2,['randompie'],3,[],4,5], how can I make it like this [1,2,3,4,5]
Here is what I've tried:
[elem for elem in [1,2,['randompie'],3,[],4,5] if type(elem)!='list']
You can use a list comprehension to easily filter all non-list elements from your list:
>>> l = [1,2,['randompie'],3,[],4,5]
>>> [el for el in l if not isinstance(el, list)]
[1, 2, 3, 4, 5]
Note I used isinstance rather than type. This is for two reasons. The former function is preferred because it takes parent classes into account. And because isinstance allows you to easily extend the list comprehension to filter out other types such as tuples or dicts:
>>> l = [1, 2, ['randompie'], 3, [], 4, 5, (1,)]
>>> [el for el in l if not isinstance(el, (list, tuple))] # filter out tuples and list
[1, 2, 3, 4, 5]
I would use list comprehension:
your_list = [1,2,['randompie'],3,[],4,5]
your_list = [thing for thing in your_list if type(thing) is not list]
If you have a list
myList = [1,2,3,4,5,6,7,8,9,0]
Is there a pythonic way to delete a defined number of items from the end of a list.
EG (pseudocode):
removeFromend(myList, 3)
print myList
>>>[1,2,3,4,5,6,7]
You can use list slicing, which I think is the most pythonic way of doing it:
end_trimm = 3
myList = myList[:-end_trimm]
If you want to mutate the list, setting a slice to an empty list is equivalent to deleting those indices.
myList = [1,2,3,4,5,6,7,8,9,0]
myList[-3:] = []
myList
Out[16]: [1, 2, 3, 4, 5, 6, 7]
This works in cases where you can't simply rebind myList to a new list, e.g. you pass your list to a function and want that function to mutate your list.
deling the slice is the direct approach
>>> myList = [1,2,3,4,5,6,7,8,9,0]
>>> del myList[-3:]
>>> myList
[1, 2, 3, 4, 5, 6, 7]
>>>
The -3 means the slice starts 3 from the end, So the general form is del myList[-n:]
I'm using python 2.7 I'm trying to figure out a way to change the names of my lists automatically.
Let me explain i have multiple lists
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 9, 3]
list3 = [8, 4, 3, 2, 1]
I would like to call the lists in a loop to determine which lists contain or do not contain a particular number.
My first thought was
x = "list" + str(i) # (where i iterates in the loop)
print x
However, using the above code only gave me the string "list1"(when i=1).
What I want is to be able to call the list that is named list1 and use the .count() operator to determine whether or not the number exists if it doesn't i want to call the next list until I'm out of lists(there will eventually be up to 30 lists).
Thanks,
Ryan
You shouldn't approach it like this. Put your lists in a container to iterate over them instead:
In [5]: for l in (list1, list2, list3):
...: print l.count(2)
...:
1
0
1
What you could do in a real-life use case is create a list of lists and fill it dynamically.
Then to get the first list that contains a given number, you could do:
In [6]: lists = [list1, list2, list3]
In [7]: next(l for l in lists if 9 in l)
Out[7]: [4, 5, 9, 3]
put the list in dict:
list1 = [1,2.4]
list2 = [2,5,6]
dlist = {1:list1,2:list2}
for k in dlist:
print dlist[k]
I have a list of tuples like this: mylist = [(1,2,3),(6,1,1),(7,8,1),(3,4,5)]. If I use the list comprehension slist = [item for sublist in mylist for item in sublist], I could get slist = [1,2,3,6,1,1,7,8,1,3,4,5].
How should I modify if I need only unique elements in slist like this [1,2,3,6,7,8,4,5]?
Use a set instead of a list.
set(slist)
If you really need it as a list then you can convert it back to a list:
slist = list(set(slist))
Note that this conversion won't preserve the original order of the elements. If you need the same order you can use this instead:
>>> result = []
>>> seen = set()
>>> for innerlist in mylist:
for item in innerlist:
if not item in seen:
seen.add(item)
result.append(item)
>>> result
[1, 2, 3, 6, 7, 8, 4, 5]
You can actually make your first part a bit easier by using itertools.chain.from_iterable and then passing the result to set, which will only retain the unique elements:
>>> mylist = [(1,2,3),(6,1,1),(7,8,1),(3,4,5)]
>>> import itertools
>>> set(itertools.chain.from_iterable(mylist))
set([1, 2, 3, 4, 5, 6, 7, 8])
import itertools
chain = itertools.chain(*mylist)
print(set(chain))
taken from Flattening a shallow list in Python and adapted for use in this question.
You should use python sets http://docs.python.org/library/sets.html
set(yourlist)
it will do the trick