python - get item number from list - python

I just asked the following question:
Python - find integer closest to 0 in list
The best answer was to use: min(lst, key=abs).
That code returns the item from the list.
How do I get the item number from the list? (i.e. 2 instead of -18)

You'd need to augment your list with indices:
min(enumerate(lst), key=lambda x: abs(x[1]))
It'll return the index and closest-to-zero value, use [0] if you only need the index.
On your example:
>>> example = [237, 72, -18, 237, 236, 237, 60, -158, -273, -78, 492, 243]
>>> min(enumerate(example), key=lambda x: abs(x[1]))
(2, -18)
>>> min(enumerate(example), key=lambda x: abs(x[1]))[0]
2
This is very efficient (worst-case O(n)); you can use example.index(min(example, key=abs)) as well, but that has to go through the list twice in the worst case (O(2n)).

>>> lst = [237, 72, -18, 237, 236, 237, 60, -158, -273, -78, 492, 243]
>>> lst.index(min(lst, key=abs))
2

Try:
lst.index(min(lst, key=abs))

One way is after finding the integer you want to find, you can use "index"...
result = min(lst, key=abs)
index = lst.index(result)
print(index) # prints 2

Related

How to sum every element in a list with the previous one?

I would like to receive the following result,
Example:
list1 = [145, 100, 125, 134, 556]
with the output being a new list with the sum results like this:
list2 = [145, 245, 225, 259, 690]
You can also use the zip trick:
>>> list(map(sum, zip(list1, [0]+list1)))
[145, 245, 225, 259, 690]
If you don't mind getting a little bit esoteric, this can be done in a single comprehension without copying the original list:
In [14]: list_1 = [145, 100, 125, 134, 556]
...: b = 0
...: list_2 = [b + (b := a) for a in list_1]
...: list_2
Out[14]: [145, 245, 225, 259, 690]
This is similar to Selcuk's answer but may be a little simpler:
list2 = [a + b for a, b in zip(list1, [0]+list1)]
Or if you don't want to use zip;
list2 = [
list1[i] + (list1[i-1] if i > 0 else 0)
for i in range(len(list1))
]
I suggest using list comprehension for this.
list1 = [145,100,125,134,556]
newLst = [list1[0]]+[sum([list1[i],list1[i-1]]) for i in range(1,len(list1))]
output
[145, 245, 225, 259, 690]
My two cents
list1 = [145,100,125,134,556]
list2 = [val if not idx else val + list1[idx - 1] for idx, val in enumerate(list1)]
I didn't come up with a list comprehension idea.
But if you wanna brute force, it'll be:
list1 = [145, 100, 125, 134, 556]
list2 = [list1[0]]
for i in range(1, len(list1)):
list2.append(list1[i] + list1[i-1])
print(list2)
And you can get
[145, 245, 225, 259, 690]
Python to the old school style!. I have created this function that takes as parameter a list and return a new list with the previous element summed. I hope can help you
def sum_list(list_numbers):
index = 0
list2 = [list_numbers[index]]
while index < (len(list_numbers) - 1):
item = list_numbers[index] + list_numbers[index + 1]
list2.append(item)
index += 1
return list2
print(sum_list(list1))
Output:
[145, 245, 225, 259, 690]
Edit: I wanted to challenge myself using a recursion approach. Maybe it's not the best approach but is here:
list2 = []
def sum_list_recursion(first_element, list_numbers, max_length):
if len(list_numbers) == 0:
return list2
elif len(list_numbers) == max_length:
list2.append(first_element)
next_element = list_numbers[0]
list_numbers = list_numbers[1:]
else:
next_element = list_numbers[0]
list_numbers = list_numbers[1:]
list2.append((first_element + next_element))
sum_list_recursion(next_element, list_numbers, max_length)
sum_list_recursion(list1[0], list1, len(list1))
print(list2)
Output:
[145, 245, 225, 259, 690]

How to compare elements in list-of-lists?

I have a list which contains list of elements(the number of elements in each inner list are not same) and I want to group all the elements in same index into separate groups and return maximum values in each group:
for example,
elements = [[89, 213, 317], [106, 191, 314], [87]]
I want to group these elements like this,
groups = [[89,106,87],[213,191],[317,314]]
the expected result is the maximum values of each list in groups : 106 ,213 and 317
I tried to group elements using following code:
w = zip(*elements)
result_list = list(w)
print(result_list)
output I got is
[(89, 106, 87)]
You can use itertools.zip_longest with fillvalue=float("-inf"):
from itertools import zip_longest
elements = [[89, 213, 317], [106, 191, 314], [87]]
out = [max(t) for t in zip_longest(*elements, fillvalue=float("-inf"))]
print(out)
Prints:
[106, 213, 317]
NOTE: zip() won't work here, because (as you stated) the number of elements in each inner list are not same. With zip_longest() the missing elements are substituted with fillvalue, in this case -infinity (and -infinity will be always the lowest value in the max() function)
Try creating a dictionary keyed with the index of each sub list, then turning the values into the new list, then map to max:
from collections import defaultdict
elements = [[89, 213, 317], [106, 191, 314], [87]]
i_d = defaultdict(list)
for sub in elements:
for i, v in enumerate(sub):
i_d[i].append(v)
maxes = list(map(max, i_d.values()))
print(maxes)
i_d:
defaultdict(<class 'list'>, {0: [89, 106, 87], 1: [213, 191], 2: [317, 314]})
maxes:
[106, 213, 317]

How to find the sum of elements in nested list?

Below is the given list:
x = [[50,55,57],[50,55,58],[50,55,60],[50,57,58],[50,57,60],[50,58,60],[55,57,58],[55,57,60],[55,58,60],[57,58,60]]
What I need here is the sum of numbers of each nested list in a different list.
For e.g [162,163,.....]
>>> x = [[50,55,57],[50,55,58],[50,55,60],[50,57,58],[50,57,60],[50,58,60],[55,57,58],[55,57,60],[55,58,60],[57,58,60]]
>>> y = [sum(i) for i in x]
>>> y
[162, 163, 165, 165, 167, 168, 170, 172, 173, 175]
You can simply do :
x = [[50,55,57],[50,55,58],[50,55,60],[50,57,58],[50,57,60],[50,58,60],[55,57,58],[55,57,60],[55,58,60],[57,58,60]]
print(list(map(sum,x)))
output:
[162, 163, 165, 165, 167, 168, 170, 172, 173, 175]
Just loop through the items.
First you loop through the internal lists:
for lst in x:
Then you sum the items in the list using the sum method:
total = sum(lst)
Together it looks like this:
new_list = list()
for lst in x:
lst = sum(lst)
new_list.append(total)
print(new_list)
Hope this helps.
Edit: I haven't used the sum method before. Which is why the two downvotes despite the program working fine.

Looping over a list and saving elements that meet a condition to a new list

I'm trying to loop over a list and save some elements to a new list: the ones that are at more than 50 greater than the previous value. My current code saves only the first value. I want [0, 76, 176, 262, 349].
list = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_list = []
for i in list:
if ((i+1)-i) > 50:
new_list.extend([i])
Solution
What I want is to save the values 0, 76, 176, 262, and 349.
So it sounds like you want to iterate over the list, and if the current element is greater than its preceding element by 50 then save it to the list and repeat. This solution assumes the original list is sorted. Let's turn this into some code.
lst = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_lst = []
for i, num in enumerate(lst):
if i == 0 or num - lst[i-1] > 50:
new_lst.append(num)
print(new_lst)
# [0, 76, 176, 262, 349]
The interesting part here is the conditional within the loop:
if i == 0 or num - lst[i-1] > 50:
The first part considers if we're at the first element, in which case I assume you want to add the element no matter what. Otherwise, get the difference between our current element and the previous element in the original list, and check if the difference is greater than 50. In both cases, we want to append the element to the list (hence the or).
Notes
You should avoid using list as a variable so you don't shadow the built-in Python type.
lst.extend([num]) is better written as lst.append(num).
enumerate(lst) allows you to easily get both the index and value of each element in a list (or any iterable).
The statement if ((i+1)-i) > 50 will always evaluate to if (1 > 50) which is false. You're looking for the next element in list, but i is simply the value of the current element. Try something like the tee() function in the itertools library to get multiple values, or something like
list = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_list = []
for i in range(len(list)):
print (i, list[i])
if i == 0 or (list[i] - list[i-1]) > 50:
new_list.append(list[i])
Keep in mind, I didn't add any checks for whether there is an i + 1 element, so you may need to do some error handling.
EDIT
This is my final edit. I would like to thank #Prune for enforcing standards :)
First, the code in PyCharm:
Second, the console output:
my solution
l = [0, 76, 91, 99, 176, 192, 262, 290, 349]
o = list(l[0]) + [a for a, b in zip(l[1:], l[:-1]) if a - b - 50 > 0]
output: [0, 76, 176, 262, 349]
for i in range(len(list)-1):
if (list[i+1]-list[i]) > 50:
new_list.append(list[i])
if list[-1] - new_list[-1] > 50:
new_list.append(list[-1]) #for the last element of list
Of course, the code can be made better. But this should work.
You can put a condition inside a list comprehension.
Also, do not give a variable the same name (list) as a built-in type.
my_list = [0, 76, 91, 99, 176, 192, 262, 290, 349]
# Start with the first element;
# then grab each element more than 50 greater than the previous one.
new_list = [my_list[0]]
new_list.extend([my_list[i] for i in range(1, len(my_list))
if my_list[i] - my_list[i-1] > 50])
print(new_list)
Output:
[0, 76, 176, 262, 349]

Generating a list of EVEN numbers in Python

Basically I need help in generating even numbers from a list that I have created in Python:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, ...]
I have tried a couple different methods, but every time I print, there are odd numbers mixed in with the evens!
I know how to generate even/odd numbers if I were to do a range of 0-100, however, getting only the even numbers from the previous mentioned list has me stumped!
P.S. I've only been using python for a couple days, if this turns out to be extremely simple, thanks in advance!
EDIT: Thanks for all the replies, with your help I've gotten through this little problem.
Here is what I ended up with to complete a little excercise asking to sum the even numbers of fibonacci sequence:
F = [1, 2]
while F[-1] < 4000000
F.append(F[-1] + F[-2])
sum(F[1::3])
4613732
Use a list comprehension (see: Searching a list of objects in Python)
myList = [<your list>]
evensList = [x for x in myList if x % 2 == 0]
This is good because it leaves list intact, and you can work with evensList as a normal list object.
Hope this helps!
The following sample should solve your problem.
Newlist = []
for x in numList:
if x % 2 == 0:
print x
Newlist.append(x)
You can do this with a list comprehension:
evens = [n for n in numbers if n % 2 == 0]
You can also use the filter function.
evens = filter(lambda x: x % 2 == 0,numbers)
If the list is very long it may be desirable to create something to iterate over the list rather than create a copy of half of it using ifilter from itertools:
from itertools import ifilter
evens = ifilter(lambda x: x % 2 == 0,numbers)
Or by using a generator expression:
evens = (n for n in numbers if n % 2 == 0)
In your specific case my_list[1::3] will work. There are always two odd integers between even integers in fibonacci: even, odd, odd, even, odd, odd.....
>>> my_list = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368]
>>>
...
>>> my_list[1::3]
[2, 8, 34, 144, 610, 2584, 10946, 46368]
Just check this
A = [i for i in range(101)]
B = [x for x in A if x%2 == 0]
print B
iterate through the list and use the modulo operator to check even
for number in list:
if (number % 2) == 0:
##EVEN
Just for fun, checking if number%2 != 1 also works ;)
evens=[x for x in evens_and_odds if number%2 != 1 ]
Note that you can do some clever things to separate out evens and odds in one loop:
evens=[]
odds=[]
numbers=[ evens, odds ]
for x in evens_and_odds:
numbers[x%2 == 1].append(x)
print evens
print odds
The above trick works because logical expressions (==, >, etc.) operating on numbers True (1) and/or False (0).
You can use list comprehension to generate a new list that contains only the even members from your original list.
data = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
then:
new_data = [i for i in data if not i%2]
yields
[2, 8, 34, 144]
Or alternatively use a generator expression if you don't need all of the numbers
at once:
new_data = (i for i in data if not i%2)
The values then would be availabe as needed, for instance if you used a for loop:
e.g.,
for val in new_data:
print val
The advantage of the generator expression is that the whole list is not generated and stored in memory at once, but values are generated as you need them which makes less demand on memory. There are other important differences you might want to read up on at some point if you are interested.
Instead of generating all Fibonacci numbers then filtering for evens, why not generate just the even values?
def even_fibs():
a,b = 1,2
while True:
yield b
a,b = a+2*b, 2*a+3*b
generates [2, 8, 34, 144, 610, 2584, 10946 ...]
then your sum code becomes:
total = 0
for f in even_fibs():
if f >= 4000000:
break
else:
total += f
or
from itertools import takewhile
total = sum(takewhile(lambda n: n<4000000, even_fibs()))
a = range(0,1000)
b = []
for c in a:
if c%2==0:
b.append(c)
print b
You could do this using the filter function as follows:
F = [1, 2]
while F[-1] < 4000000:
F.append(F[-1] + F[-2])
print(F)
print('\n')
#create the variable that could store the sorted values from the list you have created.
sorted_number=list(filter(lambda x:x%2==0,F))
print(sorted_number)
You could use a for and if loop using the length function, like this:
for x in range(len(numList)):
if x%2 == 0:
print(x)
NewList.append(x)
Basically you should create a variable and put your list in and then sort your even numbers list by adding it only the even numbers
numbers = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, ...]
even = [e for e in numbers if e%2==0]
Here are some of the different ways to get even numbers:
CASE 1
in this case, you have to provide a range
lst = []
for x in range(100):
if x%2==0:
lst.append(x)
print(lst)
CASE 2
this is a function and you have to pass a parameter to check if it is an even no or not
def even(rangeno):
for x in range(rangeno):
if rangeno%2 == 0:
return rangeno
else:
return 'No an Even No'
even(2)
CASE 3
checking the values in the range of 100 to get even numbers through function with list comprehension
def even(no):
return [x for x in range(no) if x%2==0]
even(100)
CASE 4
This case checks the values in list and prints even numbers through lambda function. and this case is suitable for the above problem
lst = [2,3,5,6,7,345,67,4,6,8,9,43,6,78,45,45]
no = list(filter(lambda x: (x % 2 == 0), lst))
print(no)

Categories

Resources