I've been searching for a solution for a few hours now. I have a variable I want to split up in a nested list.
points ="""M445,346c28.8,0,56,11.2,76.4,31.6C541.8,398,553,425.2,553,454s-11.2,56-31.6,76.4C501,550.8,473.8,562,445,562
s-56-11.2-76.4-31.6C348.2,510,337,482.8,337,454s11.2-56,31.6-76.4S416.2,346,445,346 M445,345c-60.2,0-109,48.8-109,109
s48.8,109,109,109s109-48.8,109-109S505.2,345,445,345L445,345z"""
newPoints = re.split(r'[A-Za-z-]', points)
It is a multiline var with x and y positions of points from a svg file.
The pattern is that it starts a new item at a letter. I would like to have it ordered something like the following. I've tried some options like above. One of the mail problems is that it keeps deleting my delimiter. :)
[
[
[command],
[x of p1, y of p1],
[x of p2, y of p2],
[x of p3, y of p3]
]
]
[
[ [M],[445,346] ],
[ [c],[28.8,0],[56,11.2],[76.4,31.6] ]
]
Any pointers are very welcome!
You can find letters and floats, and then group:
import re
import itertools
points ="""M445,346c28.8,0,56,11.2,76.4,31.6C541.8,398,553,425.2,553,454s-11.2,56-31.6,76.4C501,550.8,473.8,562,445,562
s-56-11.2-76.4-31.6C348.2,510,337,482.8,337,454s11.2-56,31.6-76.4S416.2,346,445,346 M445,345c-60.2,0-109,48.8-109,109
s48.8,109,109,109s109-48.8,109-109S505.2,345,445,345L445,345z"""
new_points = [list(b) for a, b in itertools.groupby(filter(None, re.findall('[a-zA-Z]+|[\d\.]+', points)), key=lambda x:re.findall('[a-zA-Z]+', x))]
final_data = [[new_points[i], [int(c) if re.findall('^\d+$', c) else float(c) for c in new_points[i+1]]] for i in range(0, len(new_points)-1, 2)]
Output:
[[['M'], [445, 346]], [['c'], [28.8, 0, 56, 11.2, 76.4, 31.6]], [['C'], [541.8, 398, 553, 425.2, 553, 454]], [['s'], [11.2, 56, 31.6, 76.4]], [['C'], [501, 550.8, 473.8, 562, 445, 562]], [['s'], [56, 11.2, 76.4, 31.6]], [['C'], [348.2, 510, 337, 482.8, 337, 454]], [['s'], [11.2, 56, 31.6, 76.4]], [['S'], [416.2, 346, 445, 346]], [['M'], [445, 345]], [['c'], [60.2, 0, 109, 48.8, 109, 109]], [['s'], [48.8, 109, 109, 109]], [['s'], [109, 48.8, 109, 109]], [['S'], [505.2, 345, 445, 345]], [['L'], [445, 345]]]
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 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.
{0: [41, 42, 183, 186, 471, 493, 639, 642, 732, 734], 1: [477, 489, 490]}
consider I have a dictionary with a list as values.
I want to find the difference between two consecutive numbers in the list and if their difference is less than, say 40, I want to fetch the second consecutive number of those two numbers taken into consideration and store all such kinds of numbers in a list.
Can anyone please help me with this.
One way to approach this:
data = {0: [41, 42, 183, 186, 471, 493, 639, 642, 732, 734], 1: [477, 489, 490]}
x = 40
{k: [b for a, b in zip(v, v[1:]) if a + x > b] for k, v in data.items()}
# {0: [42, 186, 493, 642, 734], 1: [489, 490]}
Or for a flat list:
[b for v in data.values() for a, b in zip(v, v[1:]) if a + 40 > b]
# [42, 186, 493, 642, 734, 489, 490]
dmarks={'A': [100,127, 130, 123, 210], 'B': [127, 130, 123, 210, 109]}
Check whether this helps :
dmarks={'A': [100,127, 130, 123, 210], 'B': [127, 130, 123, 210, 109]}
a,b,c=dmarks['A'],dmarks['B'],[]
for i in a:
if i in b:
c.append(i)
print(c)
if you can not use sets I suggest iterating through the list.
dmarks={'A': [100,127, 130, 123, 210], 'B': [127, 130, 123, 210, 109,]}
def find_common(a,b):
return [value for value in a if value in b]
results = find_common(dmarks['A'], dmarks['B'])
print(results)
Try:
res = [a for a in dmarks['A'] if (a in dmarks['A']) and (a in dmarks['B'])]
# [127, 130, 123, 210]
I have two copies of a list, one sorted, one isn't, in a dictionary which serve to find the index of any number in the list, starting with the largest. When I print the lists the output is as follows:
wealth_comp = {
'Wealth1': [131, 127, 125, 125, 123, 121, 121, 117, 115, 107, 105, 101],
'Wealth2': [127, 125, 121, 117, 105, 121, 107, 123, 131, 101, 115, 125]
}
but when I run
index = wealth_comp["Wealth2"].index([wealth_comp["Wealth1"][x]])
it gives me
ValueError: [131] is not in list
when it is in the list.
[131] is clearly not in the list. 131 is. So get rid of [] brackets.
index = wealth_comp["Wealth2"].index(wealth_comp["Wealth1"][x])
>>>Wealth_Comp = {
'Wealth1':131,127,125,125,123,121,121,117,115,107,105,101],
'Wealth2':[127,125,121,117,105,121,107,123,131,101,115,125]
}
>>> index = wealth_comp["Wealth2"].index(131)
>>> index`
8
Cheers