I have a list [6, 63, 131, 182, 507, 659, 669]
and would like to create a new list of pairs that looks like this:
[(7,63),(64,131),(132,182),(183,507),(508,659),(660,669)]
When I use the below code:
list = [6, 63, 131, 182, 507, 659, 669]
line_num = 0
for idx,i in enumerate(list):
print(list[idx]+1,list[idx+1])
I get below error:
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
5 pass
6 else:
----> 7 print(city_index[idx]+1,city_index[idx+1])
IndexError: list index out of range
How do I end the loop before I get an error?
Consider using zip instead. This frees you from worrying about list indices (for the most part).
lst = [6, 63, 131, 182, 507, 659, 669]
for x, y in zip(lst, lst[1:]):
print(x+1, y)
If you don't like the idea of making a shallow copy of lst, use itertools.islice instead.
from itertools import islice
lst = [6, 63, 131, 182, 507, 659, 669]
for x, y in zip(lst, islice(lst, 1, None)):
print(x+1, y)
Or, use itertools.pairwise, introduced in Python 3.10
for x, y in pairwise(lst):
print(x+1, y)
Use slicing, and it returns everything of the message but the last element ie :-1
list = [6, 63, 131, 182, 507, 659, 669]
line_num = 0
for idx,i in enumerate(list[:-1]):
print(list[idx]+1,list[idx+1])
l = [6, 63, 131, 182, 507, 659, 669]
new_l = []
for i in range(1, len(l)):
new_l.append((l[i-1] + 1, l[i]))
print(new_l)
output:
[(7, 63), (64, 131), (132, 182), (183, 507), (508, 659), (660, 669)]
You loop until the length of the list - 1 to avoid out of range:
lst = [6, 63, 131, 182, 507, 659, 669]
pairs = []
for i in range(len(lst)-1):
pairs.append((lst[i]+1, lst[i+1]))
nums = [6, 63, 131, 182, 507, 659, 669]
pairs = [(nums[i] + 1, nums[i + 1]) for i in range(len(nums) - 1)]
You could do this in a list comprehension and stop the loop at len(nums) - 1 instead of len(nums). You probably don't want to call a variable list because that's a special word in python.
Related
Take these lists:
[545, 766, 1015]
[546, 1325, 2188, 5013]
[364, 374, 379, 384, 385, 386, 468, 496, 497, 547]
My actual pattern is just finding numbers that are ascending by one, only one from each list (For this example, would be 545, 546 and 547).
After actually finding this exists, I want the first number in the sequence to be returned to me so I can continue with my other calculations.
Preferred code execution example:
>>>[12, 64, 135, 23] # input lists
>>>[84, 99, 65]
>>>[66, 234, 7, 43, 68]
>>>[64, 65, 66] # found numbers by said pattern.
>>>return 64
I have not thought of any function worthy to be written ...
A series is valid only for all numbers in the first list only if n+1 is in the next list, n+2 in the one after etc.
You can use set operations and short-circuiting with all to make searching efficient:
lists = [[545, 766, 1015],
[546, 1325, 2188, 5013],
[364, 374, 379, 384, 385, 386, 468, 496, 497, 547],
]
sets = list(map(set, lists))
out = [x for x in lists[0] if all(x+i in s for i, s in enumerate(sets[1:], start=1))]
Output:
[545]
as a function:
def find_successive(lists):
sets = list(map(set, lists[1:]))
return [x for x in lists[0] if all(x+i in s for i, s in
enumerate(sets, start=1))
]
find_successive([[12, 64, 135, 23],[84, 99, 65],[66, 234, 7, 43, 68]])
# [64]
find_successive([[12, 64, 135, 23],[84, 99, 65, 24],[66, 234, 7, 25, 43, 68]])
# [64, 23]
Alternative approach, still using sets for efficiency. Generate sets of the lists, removing 1 for the second list values, 2 for the third, etc. Then find the sets intersection:
def find_successive(lists):
sets = [{x-i for x in l} for i,l in enumerate(lists)]
return set.intersection(*sets)
# or, shorter syntax
def find_successive(lists):
return set(lists[0]).intersection(*({x-i for x in l} for i, l in enumerate(lists[1:], start=1)))
find_successive([[12, 64, 135, 23],[84, 99, 65, 24],[66, 234, 7, 25, 43, 68]])
# {23, 64}
def search(a,b,c):
for val in a:
if (val+1) in b and (val+2) in c:
return val
print(search([545, 766, 1015],[546, 1325, 2188, 5013],[364, 374, 379, 384, 385, 386, 468, 496, 497, 547]))
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]
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.
This is kind of hard to describe so I'll show it mainly in code. I'm taking a List of a List of numbers and appending it to a masterList.
The first list in master list would be the first element of each list. I would insert 0 in it's appropriate index in the master list. Then I would move on to the next list. I would choose the first element of the 2nd list and append it to the second list in the master list, since it's index would be 1, I would insert 0 to the first index of that list. This is WAY confusing, please comment back if you have any questions about it. I'll answer back fast. This is really bugging me.
ex:
L = [[], [346], [113, 240], [2974, 1520, 684], [169, 1867, 41, 5795]]
What i want is this:
[[0,346,113,2974,169],[346,0,240,1520,1867],[113,240,0,684,41],[2974,1520,684,0,5795],[169,1867,41,5795,0]]
IIUC, you want something like
>>> L = [[], [346], [113, 240], [2974, 1520, 684], [169, 1867, 41, 5795]]
>>> [x+[0]+[L[j][i] for j in range(i+1, len(L))] for i, x in enumerate(L)]
[[0, 346, 113, 2974, 169], [346, 0, 240, 1520, 1867],
[113, 240, 0, 684, 41], [2974, 1520, 684, 0, 5795],
[169, 1867, 41, 5795, 0]]
which might be easier to read in expanded form:
combined = []
for i, x in enumerate(L):
newlist = x + [0]
for j in range(i+1, len(L)):
newlist.append(L[j][i])
combined.append(newlist)
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