web-dev-qa-db-fra.com

Python tranche les premier et dernier éléments de la liste

Est-il possible de ne trancher que le premier et le dernier élément d'une liste?

Par exemple; Si c'est ma liste:

>>> some_list
['1', 'B', '3', 'D', '5', 'F']

Je veux faire ceci (évidemment [0,-1] N'est pas une syntaxe valide):

>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'

Certaines choses que j'ai essayées:

In [3]: some_list[::-1]
Out[3]: ['F', '5', 'D', '3', 'B', '1']

In [4]: some_list[-1:1:-1]
Out[4]: ['F', '5', 'D', '3']

In [5]: some_list[0:-1:-1]
Out[5]: []
...
58
chown

Une manière:

some_list[::len(some_list)-1]

Une meilleure façon (n'utilise pas le découpage en tranches, mais est plus facile à lire):

[some_list[0], some_list[-1]]
84
mgilson

Je pensais juste que je montrerais comment faire cela avec l'indexation sophistiquée de Numpy:

>>> import numpy
>>> some_list = ['1', 'B', '3', 'D', '5', 'F']
>>> numpy.array(some_list)[[0,-1]]
array(['1', 'F'], 
      dtype='|S1')

Notez qu’elle prend également en charge les emplacements d’index arbitraires, pour lesquels la méthode [::len(some_list)-1] ne fonctionnerait pas:

>>> numpy.array(some_list)[[0,2,-1]]
array(['1', '3', 'F'], 
      dtype='|S1')

Comme le souligne DSM, vous pouvez faire quelque chose de similaire avec itemgetter :

>>> import operator
>>> operator.itemgetter(0, 2, -1)(some_list)
('1', '3', 'F')
12
jterrace
first, last = some_list[0], some_list[-1]
10
Katriel

La réponse unique de Python 3 (qui n'utilise ni le découpage en tranches ni le reste de la list, mais pourrait être assez bon de toute façon) utilise des généralisations de décompression pour obtenir first et last séparé du milieu:

first, *_, last = some_list

Le choix de _ _ en tant que fourre-tout pour le "reste" des arguments est arbitraire; ils seront stockés dans le nom _ qui est souvent utilisé en remplacement de "choses qui ne me dérangent pas".

Contrairement à beaucoup d'autres solutions, celle-ci garantira qu'il y a au moins deux éléments dans la séquence; s'il n'y en a qu'un (si first et last seraient identiques), une exception sera déclenchée (ValueError).

6
ShadowRanger

Vous pouvez le faire comme ça:

some_list[0::len(some_list)-1]
6
Oleh Prypin

Certaines personnes répondent à la mauvaise question, semble-t-il. Vous avez dit que vous voulez faire:

>>> first_item, last_item = some_list[0,-1]
>>> print first_item
'1'
>>> print last_item
'F'

En d'autres termes, vous souhaitez extraire les premier et dernier éléments, chacun dans des variables distinctes.

Dans ce cas, les réponses de Matthew Adams, pemistahl et katrielalex sont valides. Ceci est juste une mission composée:

first_item, last_item = some_list[0], some_list[-1]

Mais plus tard, vous dites une complication: "Je le divise dans la même ligne, et il faudrait passer du temps à le diviser deux fois:"

x, y = a.split("-")[0], a.split("-")[-1]

Donc, pour éviter deux appels split (), vous ne devez agir que sur la liste résultant de la scission unique.

Dans ce cas, essayer de faire trop dans une ligne nuit à la clarté et à la simplicité. Utilisez une variable pour contenir le résultat de la division:

lst = a.split("-")
first_item, last_item = lst[0], lst[-1]

D'autres réponses ont répondu à la question "Comment obtenir une nouvelle liste, constituée du premier et du dernier élément d'une liste?" Ils ont probablement été inspirés par votre titre, qui mentionne le découpage en tranches, ce que vous ne voulez vraiment pas, selon une lecture attentive de votre question.

Selon ce que je sais, il existe 3 façons d’obtenir une nouvelle liste avec le 0e et le dernier élément d’une liste:

>>> s = 'Python ver. 3.4'
>>> a = s.split()
>>> a
['Python', 'ver.', '3.4']

>>> [ a[0], a[-1] ]        # mentioned above
['Python', '3.4']

>>> a[::len(a)-1]          # also mentioned above
['Python', '3.4']

>>> [ a[e] for e in (0,-1) ] # list comprehension, nobody mentioned?
['Python', '3.4']

# Or, if you insist on doing it in one line:
>>> [ s.split()[e] for e in (0,-1) ]
['Python', '3.4']

L’avantage de l’approche de compréhension de liste est que l’ensemble des index du tuple peut être arbitraire et généré par programme.

6
crobc1

Et ça?

>>> first_element, last_element = some_list[0], some_list[-1]
5
pemistahl

En fait, je viens de comprendre:

In [20]: some_list[::len(some_list) - 1]
Out[20]: ['1', 'F']
4
chown

Vous pouvez utiliser quelque chose comme

y[::max(1, len(y)-1)]

si vous voulez vraiment utiliser le découpage en tranches. L'avantage est qu'il ne peut pas générer d'erreur d'index et fonctionne également avec des listes de longueur 1 ou 0.

2
Chiel ten Brinke

Ce n'est pas une "tranche", mais une solution générale qui n'utilise pas d'indexation explicite et fonctionne pour le scénario où la séquence en question est anonyme (vous pouvez donc créer et "découper" sur la même ligne, sans créer deux fois et indexer deux fois): operator.itemgetter

import operator

# Done once and reused
first_and_last = operator.itemgetter(0, -1)

...

first, last = first_and_last(some_list)

Vous pouvez simplement le mettre comme (après from operator import itemgetter par souci de brièveté au moment de l’utilisation):

first, last = itemgetter(0, -1)(some_list)

mais si vous réutilisez beaucoup le getter, vous pouvez sauvegarder le travail de recréation (et lui donner un nom utile, auto-documenté) en le créant une fois à l'avance.

Ainsi, pour votre cas d'utilisation spécifique, vous pouvez remplacer:

x, y = a.split("-")[0], a.split("-")[-1]

avec:

x, y = itemgetter(0, -1)(a.split("-"))

et split une seule fois sans stocker l'intégralité de list dans un nom persistant pour vérification de len, double indexation, etc.

Notez que itemgetter pour plusieurs éléments retourne un Tuple, pas un list, donc si vous ne le décompressez pas sous des noms spécifiques, et avez besoin d'un vrai list, vous devez insérer l’appel dans le constructeur list.

2
ShadowRanger

Cas plus général: retourne N points de chaque fin de liste

Les réponses fonctionnent pour le premier et le dernier, mais certains, comme moi, peuvent rechercher une solution qui peut être appliquée à un cas plus général dans lequel vous pouvez renvoyer les N premiers points des deux côtés de la liste (supposons que vous ayez une liste triée et ne veulent que le 5 plus haut ou le plus bas), je suis venu avec la solution suivante:

In [1]
def GetWings(inlist,winglen):
    if len(inlist)<=winglen*2:
        outlist=inlist
    else:
        outlist=list(inlist[:winglen])
        outlist.extend(list(inlist[-winglen:]))
    return outlist

et un exemple pour renvoyer les 3 derniers et derniers chiffres de la liste 1-10:

In [2]
GetWings([1,2,3,4,5,6,7,8,9,10],3)

#Out[2]
#[1, 2, 3, 8, 9, 10]
2
Vlox

Une autre solution python3 utilise la décompression de Tuple avec le caractère "*":

first, *_, last = range(1, 10)
1
Keith

Celles-ci sont toutes intéressantes, mais que se passe-t-il si vous avez un numéro de version et que vous ne connaissez pas la taille d’un segment de la chaîne et que vous souhaitez supprimer le dernier segment? Quelque chose comme 20.0.1.300 et je veux finir avec 20.0.1 sans le 300 à la fin. J'ai ceci jusqu'à présent:

str('20.0.1.300'.split('.')[:3])

qui retourne sous forme de liste en tant que:

['20', '0', '1']

Comment puis-je le récupérer dans une seule chaîne séparée par des points

20.0.1
0
Keith