Indexing list using tuple or list [duplicate] - python

If I have a list of lists and just want to manipulate an individual item in that list, how would I go about doing that?
For example:
List1 = [[10,13,17],[3,5,1],[13,11,12]]
What if I want to take a value (say 50) and look just at the first sublist in List1, and subtract 10 (the first value), then add 13, then subtract 17?

You can access the elements in a list-of-lists by first specifying which list you're interested in and then specifying which element of that list you want. For example, 17 is element 2 in list 0, which is list1[0][2]:
>>> list1 = [[10,13,17],[3,5,1],[13,11,12]]
>>> list1[0][2]
17
So, your example would be
50 - list1[0][0] + list1[0][1] - list1[0][2]

You can use itertools.cycle:
>>> from itertools import cycle
>>> lis = [[10,13,17],[3,5,1],[13,11,12]]
>>> cyc = cycle((-1, 1))
>>> 50 + sum(x*next(cyc) for x in lis[0]) # lis[0] is [10,13,17]
36
Here the generator expression inside sum would return something like this:
>>> cyc = cycle((-1, 1))
>>> [x*next(cyc) for x in lis[0]]
[-10, 13, -17]
You can also use zip here:
>>> cyc = cycle((-1, 1))
>>> [x*y for x, y in zip(lis[0], cyc)]
[-10, 13, -17]

This code will print each individual number:
for myList in [[10,13,17],[3,5,1],[13,11,12]]:
for item in myList:
print(item)
Or for your specific use case:
((50 - List1[0][0]) + List1[0][1]) - List1[0][2]

List1 = [[10,-13,17],[3,5,1],[13,11,12]]
num = 50
for i in List1[0]:num -= i
print num

50 - List1[0][0] + List[0][1] - List[0][2]
List[0] gives you the first list in the list (try out print List[0]). Then, you index into it again to get the items of that list. Think of it this way: (List1[0])[0].

for l in list1:
val = 50 - l[0] + l[1] - l[2]
print "val:", val
Loop through list and do operation on the sublist as you wanted.

new_list = list(zip(*old_list)))
*old_list unpacks old_list into multiple lists and zip picks corresponding nth element from each list and list packs them back.

to print every individual element in double list
list1=[[1,2,3],[4,5,6],[7,8,9]]
for i in range(len(list1)):
for j in range(len(list1[i])):
print(list1[i][j])

Related

Pop a largest number in a list to another list, python

I want to get the max() nubmer in a list and then pop it to another list, (list1).
x = [66,1,4,3,6,55]
list1 = []
for i in x:
x.pop(max(x))
#poped item saved to list1
print(list1)
This is my approach but i get the error " pop index out of range". What am i doing wrong ? And i really dont know how to further pop() an item and return it to an empty list.The result should be a list1 with numbers from highest to lowest. Please, dont post any other algorithm with built in functions like sort(). Thanks.
You need to provide the index of the max element in a list to pop
x = [66,1,4,3,6,55]
list1 = [x.pop(x.index(max(x)))]
print(list1)
Output
[66]
Request from Comments:
x = [66,1,4,3,6,55]
list1 = []
while x:
list1.append(x.pop(x.index(max(x))))
print(list1)
In python pop method's argument is index, But you are passing values.
x = [66,1,4,3,6,55]
list1 = []
for i in range(len(x)):
list1.append(x.pop(x.index(max(x))))
print(list1)
Try this.
You can try:
>>> x = [66,1,4,3,6,55]
>>> list_popped = []
>>> list_popped.append(x.pop(x.index(max(x))))
>>> print list_popped
[66]
>>> print x
[1, 4, 3, 6, 55]
List pop method takes index of the element as argument. you are providing the item itself. In your example the first value will be 66 and you are trying pop(66), there is no item at 66th index(the length of the list is less than 66).
try the following code
x = [66,1,4,3,6,55]
list1 = []
for i in range(len(x)):
max_val = max(x)
max_val_index = x.index(max_val)
list1.append(max_val)
x.pop(max_val_index)
print(list1)
Output: [66, 55, 6, 4, 3, 1]

Operation with values at specific indexes in a list of list

I'm currently writing a little script in python (2.x), and there's a portion of the code that I'd like to improve without knowing how to do so.
I have a list of lists that looks like the following:
my_list = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]
I need to get the sum of all the integers at the index 1 and the sum of all the integers at the index 2. To do so, I currently have:
sum1, sum2 = 0, 0
for i in my_list:
sum1 += i[1]
sum2 += i[2]
What could be a more pythonic way to do that? Maybe using reduce and a lambda function or something?
A more pythonic way to do that would be using the sum function along with the for ... in ... generator and do all the work in a single line, like this:
sum1, sum2 = sum(x[1] for x in my_list), sum(x[2] for x in my_list)
The most Pythonic would probably be list comprehensions:
my_list = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]
Summations:
sum1 = sum(l[1] for l in my_list)
sum2 = sum(l[2] for l in my_list)
Which returns:
sum1 = 11
sum2 = 14
You could do sum(x[1] for x in in my_list), sum(x[2] for x in my_list) if you don't mind looping twice.
or reduce(lambda acc, l: (acc[0] + l[1], acc[1] + l[2]), my_list, (0, 0)) if you want to do it both at once. This will return a tuple with the sum of [1] on the first element, and [2] on the second
You can use zip and list comprehension
>>> lst = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]
>>> [sum(i) for i in list(zip(*lst))[1:3]]
[11, 14]
Or use zip and islice class from itertools
>>> from itertools import islice
>>> [sum(i) for i in islice(zip(*lst), 1, 3)]
[11, 14]
Here's a one liner that doesn't use a generator expression. Use zip plus unpacking to transpose the list, then run sum on all the numeric columns using map.
>>> map(sum, zip(*my_list)[1:-1])
[11, 14]
Unfortunately it's a little wordier in 3.X since you can't slice a zip object.
a,b = map(sum, list(zip(*my_list))[1:-1])
You can use reduce but, since the elements in your sequence are lists, you'll need to set an initial value of 0. In Example:
reduce(lambda total, list: total+list[1], my_list, 0) # integers at index 1
reduce(lambda total, list: total+list[2], my_list, 0) # integers at index 2

How to access an element based on the element appears before it in python list

In python list, I would like to access elements based on an element that appears before them. So for example, in a given list such as:
x = [1,2,25,1,67,8,9,1,99]
I would like to filter out 2,67,99 since they all have 1 preceding them. I was thinking about using index but index only returns the first element.
You want to use indexing and for loop.
my_list = [1,2,25,1,67,8,9,1,99]
for i in range(len(my_list)): # len() returns length of an array
if my_list[i] == 1: # here you check if 'i' element of my_list is equal to 1
try:
print(my_list[i+1]) # here you are printing 'i+1' element of my_list
except IndexError:
pass
result of this code is:
2
67
99
You can use zip along with list slicing as
>>> x = [1,2,25,1,67,8,9,1,99]
>>> for i,j in zip(x[:-1],x[1:]):
... if i==1:
... print j
...
2
67
99
This can be written in a single list comprehension as
[j for i,j in zip(x[:-1],x[1:]) if i==1]
You could use list comprehension and enumerate(), like this:
>>> [y for i, y in enumerate(x[1:]) if x[i] == 1]
[2, 67, 99]

Python: Appending the index number of a string item in a list to that item

For any given list of string items, e.g.
my_list = ['foo', 'bar', 'baz', 'foo']
How does one append the index number of each item to it's corresponding item in the list? Forming a new list with the format, e.g.
new_list = ['foo0', 'bar1', 'baz2', 'foo3']
My example list only has four items, but I'm interested in a generalised answer for an arbitrary number of string items (something that works as well for a list of 4,000 string items as it does for 4)
Cheers!
A simpler way:
new_list = [elm + str(index) for index, elm in enumerate(my_list)]
UPDATE: With Python 3.6+ and formatted strings literals you can get a more readable code:
new_list = [f'{elm}{index}' for index, elm in enumerate(my_list)]
A straight for loop would work:
counter = 0
new_list = []
for each_item in the_list:
new_list.append(each_item + str(counter))
counter += 1
A list comprehension with enumerate() would also be fine, but less readable:
new_list = [each_item + str(index) for each_item, index in enumerate(the_list)]
try this.
EDIT: Explanation: The function below takes a list as an input and returns a list with the element numbers appended to the item. The number appended to the end of each item in the list is padded with zeros based on the length of the input list. So a list of length 30 with have appended numbers 00 through 29; a list of 3901 will have appended numbers 0000 through 3900.
from numpy import log10
def numberedList(inlist):
i = 0
z = int(log10(len(inlist))) + 1
outlist = []
for element in inlist:
outlist.append(str(element) + str(i).zfill(z))
i = i + 1
return outlist
To create a list from a static list and a repeating list:
# need: ['A','B','C','First1','Middle1','Last1','First2','Middle2','Last2',...]
['A','B','C']+[s+str(n) for n in range(1,len(names)+1) for s in ['First','Middle','Last']]

Joining two list whereby the last element of list "A" and first element of list "B" are concatenated

I have two lists that I am concatenating using listA.extend(listB).
What I need to achieve when I extend listA is to concatenate the last element of listA with the first element of listB
an example of my lists are as below
end of listA = ... '1633437.0413', '5417978.6108', '1633433.2865', '54']
start of listB = ['79770.3904', '1633434.364', '5417983.127', '1633435.2672', ...
obviously when I extend I get the below (note the 54)
'5417978.6108', '1633433.2865', '54', '79770.3904', '1633434.364', '5417983.127
Below is what I want to achieve where the last and first elements are concatenated
[...5417978.6108', '1633433.2865', '*5479770.3904*', '1633434.364', '5417983.127...]
any ideas?
You can achieve that in two steps:
A[-1] += B[0] # update the last element of A to tag on contents of B[0]
A.extend(B[1:]) # extend A with B but exclude the first element
Example:
>>> A = ['1633437.0413', '5417978.6108', '1633433.2865', '54']
>>> B = ['79770.3904', '1633434.364', '5417983.127', '1633435.2672']
>>> A[-1] += B[0]
>>> A.extend(B[1:])
>>> A
['1633437.0413', '5417978.6108', '1633433.2865', '5479770.3904', '1633434.364', '5417983.127', '1633435.2672']
newlist = listA[:-1] + [listA[-1] + listB[0]] + listB[1:]
or if you want to extend listA "inplace"
listA[-1:] = [listA[-1] + listB[0]] + listB[1:]
One-liner with list comprehension (just for the sake of list comprehension actually :)):
[(x + listB[0]) if i == len(listA) - 1 else x for i, x in enumerate(listA)] + listB[1:]

Categories