Skaidra izpratne par šķēļu pierakstu

Man ir nepieciešams labs skaidrojums (atsauces ir plus) par Python'slice notācija.

Man šķiet, ka šī notācija ir mazliet jāiedziļinās.

Izskatās, ka tā ir ārkārtīgi jaudīga, bet es to vēl neesmu īsti apguvis.

Risinājums

Tas ir pavisam vienkārši:

a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array

Ir arī stepa vērtība, ko var izmantot kopā ar jebkuru no iepriekš minētajām:

a[start:stop:step] # start through not past stop, by step

Galvenais ir atcerēties, ka :stop vērtība ir pirmā vērtība, kas nav izvēlētajā šķēlumā. Tātad atšķirība starp stop un start ir atlasīto elementu skaits (ja step ir 1, kas ir noklusējuma vērtība).

Otra īpatnība ir tā, ka start vai stop var būt negatīvs skaitlis, kas nozīmē, ka tas tiek skaitīts no masīva beigām, nevis sākuma. Tātad:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

Līdzīgi arī steps var būt negatīvs skaitlis:

a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

Python ir laipns pret programmētāju, ja ir mazāk elementu, nekā jūs lūdzat. Piemēram, ja jūs pieprasāt a[:-2] un a satur tikai vienu elementu, jūs kļūdu vietā saņemsiet tukšu sarakstu. Dažreiz jūs labprātāk izvēlaties kļūdu, tāpēc jums ir jāapzinās, ka tā var notikt.

Saistība ar objektu slice()

Iepriekš minētajā kodā griešanas operators [] faktiski tiek izmantots kopā ar slice() objektu, izmantojot : notāciju (kas ir derīga tikai [] ietvaros), t.i..:

a[start:stop:step]

ir ekvivalents:

a[slice(start, stop, step)]

Slice objekti arī uzvedas nedaudz atšķirīgi atkarībā no argumentu skaita, līdzīgi kā range(), t.i., tiek atbalstīti gan slice(stop), gan slice(start, stop[, step]). Lai izlaistu dotā argumenta norādīšanu, var izmantot None, tādējādi, piemēram, a[start:] ir ekvivalents a[slice(start, None)] vai a[::-1] ir ekvivalents a[slice(None, None, -1)].

Lai gan uz : balstītā notācija ir ļoti noderīga vienkāršas sagriešanas gadījumā, tieša slice() objektu izmantošana vienkāršo sagriešanas programmatisko ģenerēšanu.

Komentāri (7)

Par to ir runāts Python pamācībā (ritiniet nedaudz uz leju, līdz nonākat līdz daļai par sagriešanu).

ASCII mākslas diagramma ir noderīga arī, lai atcerētos, kā darbojas griezumi:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

Viens no veidiem, kā atcerēties, kā darbojas griezumi, ir iedomāties, ka indeksi ir norādes uz starp rakstzīmēm, kur pirmās rakstzīmes kreisā mala ir numurēta 0. Tad n rakstzīmju virknes pēdējās rakstzīmes labajai malai ir indekss n.

Komentāri (2)

Gramatikas atļauto iespēju uzskaitījums:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

Protams, ja (high-low)%stride != 0, tad beigu punkts būs nedaudz zemāk par high-1.

Ja stride ir negatīvs, nedaudz mainās secība, jo mēs skaitām uz leju:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

Paplašināto griezumu (ar komatiem un elipsēm) pārsvarā izmanto tikai īpašas datu struktūras (piemēram, NumPy); pamata secības tos neatbalsta.

>>> class slicee:
...     def __getitem__(self, item):
...         return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
Komentāri (3)