Prenez le contenu d'une liste et ajoutez-le à une autre liste

193

J'essaie de comprendre s'il est logique de prendre le contenu d'une liste et de l'ajouter à une autre liste.

J'ai la première liste créée via une fonction de boucle, qui obtiendra des lignes spécifiques d'un fichier et les enregistrera dans une liste.

Ensuite, une deuxième liste est utilisée pour enregistrer ces lignes, et démarrer un nouveau cycle sur un autre fichier.

Mon idée était d'obtenir la liste une fois que le cycle for est terminé, de la vider dans la deuxième liste, puis de démarrer un nouveau cycle, de vider à nouveau le contenu de la première liste dans la seconde mais en l'ajoutant, ainsi la deuxième liste sera la somme de tous les fichiers de liste plus petits créés dans ma boucle. La liste ne doit être ajoutée que si certaines conditions sont remplies.

Cela ressemble à quelque chose de similaire à ceci:

# This is done for each log in my directory, i have a loop running
for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    for item in list1:
        if "string" in item: #if somewhere in the list1 i have a match for a string
            list2.append(list1) # append every line in list1 to list2
            del list1 [:] # delete the content of the list1
            break
        else:
            del list1 [:] # delete the list content and start all over

Cela a-t-il un sens ou devrais-je choisir un itinéraire différent?

J'ai besoin de quelque chose d'efficace qui ne prendrait pas trop de cycles, car la liste des journaux est longue et chaque fichier texte est assez gros; j'ai donc pensé que les listes correspondraient à l'objectif.

user1006198
la source

Réponses:

371

Tu veux probablement

list2.extend(list1)

au lieu de

list2.append(list1)

Voici la différence:

>>> a = range(5)
>>> b = range(3)
>>> c = range(2)
>>> b.append(a)
>>> b
[0, 1, 2, [0, 1, 2, 3, 4]]
>>> c.extend(a)
>>> c
[0, 1, 0, 1, 2, 3, 4]

Puisqu'accepte list.extend()un itérable arbitraire, vous pouvez également remplacer

for line in mylog:
    list1.append(line)

par

list1.extend(mylog)
Sven Marnach
la source
Oui, append est pour un élément, extend est comme concat.
Catalina Chircu le
13

Jetez un œil à itertools.chain pour un moyen rapide de traiter de nombreuses petites listes comme une seule grande liste (ou au moins comme une seule grande itérable) sans copier les petites listes:

>>> import itertools
>>> p = ['a', 'b', 'c']
>>> q = ['d', 'e', 'f']
>>> r = ['g', 'h', 'i']
>>> for x in itertools.chain(p, q, r):
        print x.upper()
Raymond Hettinger
la source
Cela semble vraiment élégant! Je vais y jeter un œil pour voir si je peux remplacer le code que j'ai déjà en utilisant itertools!
user1006198
3

Cela semble assez raisonnable pour ce que vous essayez de faire.

Une version légèrement plus courte qui s'appuie sur Python pour faire plus de gros travaux pourrait être:

for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    if any(True for line in list1 if "string" in line):
        list2.extend(list1)
    del list1

    ....

L' (True for line in list1 if "string" in line)itère listet émet Truechaque fois qu'une correspondance est trouvée. any()utilise une évaluation de court-circuit pour revenir Truedès que le premier Trueélément est trouvé. list2.extend()ajoute le contenu de list1à la fin.

Kirk Strauser
la source
1
any(True for line in list1 if "string" in line)est plus clairement écrit comme any("string" in line for line in list1).
Karl Knechtel
Bon point, @KarlKnechtel, bien qu'ils soient subtilement différents. Votre version émet toujours quelque chose , True ou False. Le mien n'émet qu'un seul True. Je n'ai aucune idée de la façon dont ces points de repère se situent ou s'il y a suffisamment de différence pour avoir de l'importance.
Kirk Strauser
Dans les deux cas, anyreçoit un générateur; aucune liste de valeurs True ou False n'est construite nulle part. Ma version renvoie plus de choses pour anyvérifier, mais en échange de ne pas faire la même vérification dans le générateur lui-même. J'imagine que c'est un lavage, mais timeitc'est ici qui fait autorité, pas moi. :)
Karl Knechtel
3

Vous pouvez également combiner deux listes (disons a, b) en utilisant l'opérateur «+». Par exemple,

a = [1,2,3,4]
b = [4,5,6,7]
c = a + b

Output:
>>> c
[1, 2, 3, 4, 4, 5, 6, 7]
Akshaya Natarajan
la source
3

Pour récapituler sur les réponses précédentes. Si vous avez une liste avec [0,1,2]et une autre avec [3,4,5]et que vous souhaitez les fusionner, alors cela devient [0,1,2,3,4,5], vous pouvez utiliser chainingou extendinget devez connaître les différences pour l'utiliser à bon escient pour vos besoins.

Extension d'une liste

En utilisant la méthode listclasses extend, vous pouvez faire une copie des éléments d'une liste sur une autre. Cependant, cela entraînera une utilisation supplémentaire de la mémoire, ce qui devrait être bien dans la plupart des cas, mais pourrait causer des problèmes si vous voulez être efficace en mémoire.

a = [0,1,2]
b = [3,4,5]
a.extend(b)
>>[0,1,2,3,4,5]

entrez la description de l'image ici

Chaînage d'une liste

Au contraire, vous pouvez utiliser itertools.chainpour câbler de nombreuses listes, ce qui renverra un soi-disant iteratorqui peut être utilisé pour parcourir les listes. Ceci est plus efficace en mémoire car il ne copie pas les éléments mais pointe simplement vers la liste suivante.

import itertools
a = [0,1,2]
b = [3,4,5]
c = itertools.chain(a, b)

entrez la description de l'image ici

Créez un itérateur qui renvoie les éléments du premier itérable jusqu'à ce qu'il soit épuisé, puis passe à l'itérable suivant, jusqu'à ce que tous les itérables soient épuisés. Utilisé pour traiter des séquences consécutives comme une seule séquence.

user1767754
la source
2

Utilisation des fonctions map()et reduce()intégrées

def file_to_list(file):
     #stuff to parse file to a list
     return list

files = [...list of files...]

L = map(file_to_list, files)

flat_L = reduce(lambda x,y:x+y, L)

Minimal "pour boucler" et modèle de codage élégant :)

pX0r
la source
0

Si nous avons une liste comme ci-dessous:

list  = [2,2,3,4]

deux façons de le copier dans une autre liste.

1.

x = [list]  # x =[] x.append(list) same 
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 1
[2, 2, 3, 4]

2.

x = [l for l in list]
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 4
2
2
3
4
Avinash
la source