0
votes

Multiplier chaque troisième élément d'une liste par deux

Données d'entrée: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Code>
Données de sortie: [1, 2, 6, 4, 5, 12, 7, 8, 18, 10] Code>

J'ai lu de nombreuses réponses où ont été suggérées d'utiliser la notation de tranche avec le premier élément incluant . Mais dans mon cas, je devrais prendre chaque 3ème élément de la liste. P>

est-il possible d'améliorer ma réalisation? P>

for index in range(len(data)):
    if (index + 1) % 3 == 0:
        data[index] = data[index] * 2


6 Réponses :


9
votes

Oui, vous pouvez le faire avec la notation de la tranche:

data[2::3] = [x*2 for x in data[2::3]]


4 commentaires

Vous pouvez améliorer cela en faisant data [2 :: 3] = (x * 2 pour x en données [2 :: 3]) . Cela utilise un générateur et évite la création d'une liste temporaire.


@Tomkarzes mais data [2 :: 3] est une liste temporaire. Pour éviter vraiment la création d'une liste temporaire, il faut utiliser data [2 :: 3] = (x * 2 pour x dans itertools.lice (données, 2, aucune, 3)) .


@blhsing Oh, bon point. Je ne faisais que regarder la liste temporaire "extérieure". Je suppose que vous pouvez aussi faire des données [2 :: 3] = (données [i] * 2 pour i dans la plage (2, len (données), 3))


En fait, affectation de la liste des tranches sera matérialiser le générateur sur une liste de toute façon, comme j'ai appris de Le dernier commentaire sur Cette réponse



3
votes

Il existe un paramètre "étape" sur la plage Itérateur: xxx

serait-ce que cela fait?


0 commentaires

3
votes

Votre solution n'est pas trop mauvaise. Il peut être amélioré en itérant simplement sur les indices désirés directement, plutôt que d'itération de tous les indices et de sauter ceux que vous ne voulez pas:

[1, 2, 6, 4, 5, 12, 7, 8, 18, 10]


0 commentaires

1
votes

Vous pouvez l'organiser un peu en passant un troisième argument à la fonction de plage (), comme celui-ci:

pour index dans la plage (2, len (données), 3): Data [index] = Data [index] * 2


0 commentaires

2
votes

Vous pouvez utiliser le cycle d'iTERTOOLS et ZIP pour associer des éléments avec leurs multiplicateurs: xxx

ou, vous pouvez utiliser énumérer () xxx / p>


0 commentaires

1
votes

... et le gagnant est:

import time


def question_by_akrapovich(data):
    for index in range(len(data)):
        if (index + 1) % 3 == 0:
            data[index] = data[index] * 2
    return data


def answer_by_Tom_Karzes_and_Prune(data):
    for index in range(2, len(data), 3):
        data[index] *= 2
    return data


def answer_by_Blorgbeard(data):
    data[2::3] = [x*2 for x in data[2::3]]
    return data


def answer_1_by_Alain_T(data):
    from itertools import cycle
    return [n * m for n, m in zip(data, cycle([1, 1, 2]))]


def answer_2_by_Alain_T(data):
    return [ n*max(1,i%3) for i,n in enumerate(data) ]


def answer_2_by_Manuel_Montoya(data):
    for index in range(2, len(data), 3):
        data[index] = data[index]*2
    return  data

def test(f):
    n = 10_000_000
    data = [i + 1 for i in range(n)]
    start_time = time.perf_counter()
    data = f(data)
    run_time = time.perf_counter() - start_time
    if n != len(data):
        print('error in list length', n, len(data))
        exit(1)
    for i in range(n):
        j = i + 1
        m = j * 2 if j % 3 == 0 else j
        if data[i] != m:
            print('error in data', i, m, data[i])
            exit(1)
    print('%.3f %s' % (run_time, f.__name__))


print('Calculation time in seconds and results validation test.')
for f in [question_by_akrapovich, answer_by_Tom_Karzes_and_Prune,
          answer_2_by_Manuel_Montoya, answer_by_Blorgbeard,
          answer_1_by_Alain_T, answer_2_by_Alain_T]:
    test(f)


0 commentaires