1
votes

Rechercher un tuple dans la liste avec le même premier élément et renvoyer une autre liste

J'ai une liste comme celle-ci en Python:

[('a', 'b', 'c'),('d','f')]

et je veux joindre des éléments qui ont le même premier élément et qui donnent le résultat suivant:

[('a', 'b'), ('a', 'c'),('d','f')]


5 commentaires

Qu'avez-vous essayé et quel est exactement le problème? De plus, votre entrée semble être une chaîne, pas une liste (elle ne serait pas syntaxiquement valide en tant que liste).


Est-ce que d et f sont supposés être 'd' et 'f' ? Est-ce que le tuple de type interne (tel que vous êtes écrit) ou des listes (selon le titre)?


modifiez-le à nouveau :)


@PatrickArtner ohk, je viens de modifier la meilleure chose attendue, comme vous voyez si un bc est une chaîne et la façon dont il a écrit d et e, signifie sûrement qu'il voulait qu'ils soient aussi une chaîne, plutôt que d'être un nom de variable.


@PatrikArtner La plupart des utilisateurs débutants font également la même erreur. Bien que je sois d'accord sur votre suggestion, merci.


3 Réponses :


0
votes

Vous ne pouvez pas modifier les tuples - ils sont immuables. Vous pouvez utiliser des listes et tout reconvertir en tuples par la suite:

[['a', 'b', 'c'], ['d', 'f']]     # all are lists
[('a', 'b', 'c'), ('d', 'f')]     # all are tuples again   

Sortie:

data = [('a', 'b'), ('a', 'c'),('d','f')]

new_data = []


for d in data                                             # loop over your data
    if new_data and new_data[-1][0] == d[0]:              # if something in new_data and 1st
        new_data[-1].extend(d[1:])                        # ones are identical: extend
    else:
        new_data.append( [a for a in d] )                 # not same/nothing in: add items

print(new_data)                   # all are lists

new_data = [tuple(x) for x in new_data]
print(new_data)                   # all are tuples again      


0 commentaires

1
votes

Voici une façon de procéder. Pour plus d'efficacité, nous construisons un dict avec la première valeur comme clé. Nous conservons les valeurs dans l'ordre dans lequel elles apparaissent (et les tuples également dans leur ordre d'origine, si vous utilisez Python> = 3.7 - sinon vous devrez utiliser un collections.OrderedDict )

def join_by_first(sequences):
    out = {}
    for seq in sequences:
        try:
            out[seq[0]].extend(seq[1:])
        except KeyError:
            out[seq[0]] = list(seq)
    return [tuple(values) for values in out.values()]

join_by_first([('a', 'b'), ('a', 'c'),('d','f')])
# [('a', 'b', 'c'), ('d', 'f')]


0 commentaires

0
votes

J'ai l'impression que la solution la plus simple est de créer un dictionnaire dans lequel:

    Les
  • clés sont les premiers éléments des tuples
  • les valeurs sont des listes contenant tous les seconds éléments des tuples

Une fois que nous avons cela, nous pouvons alors construire la liste de sortie:

[('a', 'b', 'c'), ('d', 'f')]

Ceci produit:

from collections import defaultdict

def merge(pairs):
    mapping = defaultdict(list)
    for k, v in pairs:
        mapping[k].append(v)
    return [(k, *v) for k, v in mapping.items()]

pairs = [('a', 'b'), ('a', 'c'),('d','f')]
print(merge(pairs))

Cette solution est en O (n) car nous n'itérons que deux fois sur chaque élément à partir de paires .


0 commentaires