Je me demandais comment obtenir une série de plages à partir d'une série de valeurs. Ce que je veux dire par là, c'est supposer que j'ai une liste de nombres: list_values ​​= [4, 3, 4, 4], et je veux convertir cela en une série de ...

0
bactro 17 mars 2021 à 01:55

4 réponses

Meilleure réponse

Au cas où vous voudriez une réponse sans rien importer.

list_values = [4, 3, 4, 4]
range_start = []
start = 0
for i, k in enumerate(list_values):
    if start == 0:
        new_range = [start, start + k]
    else:
        new_range = [range_start[i-1][1], start + k]
    range_start.append(new_range)
    start += k + 1

Vous donne une range_start sortie de: [[0, 4], [4, 8], [8, 13], [13, 18]]

2
Cambuchi 17 mars 2021 à 00:42

Vous pouvez utiliser une compréhension de liste avec zip:

l = [4, 3, 4, 4] 
k = [sum(l[:i])+a+i for i, a in enumerate(l)]
#as full ranges
result = [list(range(a, b+1)) for a, b in zip([0]+k[:-1], k)]
#start and end indices:
result = list(zip([0]+k[:-1], k))

Production

[[0, 1, 2, 3, 4], [4, 5, 6, 7, 8], [8, 9, 10, 11, 12, 13], [13, 14, 15, 16, 17, 18]]
[(0, 4), (4, 8), (8, 13), (13, 18)]
0
Ajax1234 17 mars 2021 à 00:33

Je suis venu avec ceci:

from collections import defaultdict

result = defaultdict(list)

prev = 0
for idx, n in enumerate(l):
  for i in range(prev, prev + n + 1):
    result[idx].append(i)
  prev = i + 1

print(result)

Production:

defaultdict(<class 'list'>, {0: [0, 1, 2, 3, 4], 1: [5, 6, 7, 8], 2: [9, 10, 11, 12, 13], 3: [14, 15, 16, 17, 18]})

EDIT inspiré par la réponse de @ crcvd:

from itertools import accumulate

l= [4, 3, 4, 4]

result = {}
prev = 0
for idx, last in enumerate(accumulate(l)):
  result[idx] = list(range(idx + prev, last + idx + 1))
  prev = last
1
Anthony Perot 16 mars 2021 à 23:51

Vous pouvez utiliser itertools.accumulate pour générer la liste des points de terminaison de droite, puis utilisez une deuxième itération pour générer les points de terminaison de gauche. Le point de terminaison droit augmente à mesure que vous ajoutez les largeurs de compartiment, et le point de terminaison gauche à un point donné est le dernier point de terminaison droit plus un.

from itertools import accumulate

list_values = [4, 3, 4, 4]

ranges = []

endpoints = list(accumulate(list_values))

for idx, value in enumerate(endpoints):
    # These ranges are closed on the left and 
    # the right.
    if idx == 0:
        ranges.append((1, value))
    else:
        ranges.append((endpoints[idx-1] + 1, value))
print(ranges)
[(1, 4), (5, 7), (8, 11), (12, 15)]

La raison de votre IndexError est que list_values est un élément de votre liste (un entier; vous masquez votre liste externe dans ce nom) et list_values[i] tente d'y accéder comme si elle étaient une liste.

2
crcvd 16 mars 2021 à 23:12