Szukaj…


Zadanie dotyczące restrukturyzacji

W zadaniach można podzielić Iterable na wartości, używając składni „rozpakowywanie”:

Niszczenie jako wartości

a, b = (1, 2)
print(a)
# Prints: 1
print(b)
# Prints: 2

Jeśli spróbujesz rozpakować więcej niż długość iterowalnego, pojawi się błąd:

a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
Python 3.x 3.0

Destrukturyzacja jako lista

Możesz rozpakować listę o nieznanej długości, używając następującej składni:

head, *tail = [1, 2, 3, 4, 5]

Tutaj wyodrębniamy pierwszą wartość jako skalar, a pozostałe wartości jako listę:

print(head)
# Prints: 1
print(tail)
# Prints: [2, 3, 4, 5]

Co odpowiada:

l = [1, 2, 3, 4, 5]
head = l[0]
tail = l[1:]

Działa również z wieloma elementami lub elementami z końca listy:

a, b, *other, z = [1, 2, 3, 4, 5]
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]

Ignorowanie wartości w zadaniach restrukturyzacji

Jeśli interesuje Cię tylko dana wartość, możesz użyć _ aby wskazać, że nie jesteś zainteresowany. Uwaga: to wciąż ustawi wartość _ , tylko większość ludzi nie używa jej jako zmiennej.

a, _ = [1, 2]
print(a)
# Prints: 1
a, _, c = (1, 2, 3)
print(a)
# Prints: 1
print(c)
# Prints: 3
Python 3.x 3.0

Ignorowanie list w zadaniach restrukturyzacyjnych

Na koniec możesz zignorować wiele wartości, używając składni *_ w przypisaniu:

a, *_ = [1, 2, 3, 4, 5]
print(a)
# Prints: 1

co nie jest tak naprawdę interesujące, ponieważ zamiast tego można użyć indeksowania na liście. Przyjemnie jest zachować pierwszą i ostatnią wartość w jednym zadaniu:

 a, *_, b = [1, 2, 3, 4, 5]
 print(a, b)
 # Prints: 1 5

lub wyodrębnij kilka wartości jednocześnie:

 a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
 print(a, b, c)
 # Prints: 1 3 5

Argumenty funkcji pakowania

W funkcjach możesz zdefiniować szereg obowiązkowych argumentów:

def fun1(arg1, arg2, arg3): 
    return (arg1,arg2,arg3)

co sprawi, że funkcja będzie możliwa do wywołania tylko wtedy, gdy podane zostaną trzy argumenty:

fun1(1, 2, 3)

i możesz zdefiniować argumenty jako opcjonalne, używając wartości domyślnych:

def fun2(arg1='a', arg2='b', arg3='c'):
    return (arg1,arg2,arg3)

więc możesz wywołać tę funkcję na wiele różnych sposobów, na przykład:

fun2(1)              → (1,b,c)
fun2(1, 2)           → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...

Ale możesz także użyć składni destrukcyjnej do spakowania argumentów, abyś mógł przypisywać zmienne za pomocą list lub dict .

Pakowanie listy argumentów

Rozważ, że masz listę wartości

l = [1,2,3]

Możesz wywołać funkcję z listą wartości jako argumentem, używając składni * :

fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')

Ale jeśli nie podasz listy, której długość odpowiada liczbie argumentów:

fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'

Pakowanie argumentów słów kluczowych

Teraz możesz także pakować argumenty za pomocą słownika. Możesz użyć operatora ** , aby powiedzieć Pythonowi, aby rozpakował dict jako wartości parametrów:

d = {
  'arg1': 1,
  'arg2': 2,
  'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)

gdy funkcja ma tylko argumenty pozycyjne (te bez wartości domyślnych), potrzebujesz, aby słownik zawierał wszystkie oczekiwane parametry i nie miał żadnych dodatkowych parametrów, w przeciwnym razie wystąpi błąd:

fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argument: 'arg3'
fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'

W przypadku funkcji, które mają opcjonalne argumenty, można spakować argumenty jako słownik w ten sam sposób:

fun2(**d)
# Returns: (1, 2, 3)

Możesz jednak pominąć wartości, ponieważ zostaną one zastąpione wartościami domyślnymi:

fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')

I tak samo jak poprzednio, nie można podać dodatkowych wartości, które nie są parametrami istniejącymi:

fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'

W świecie rzeczywistym funkcje mogą mieć argumenty pozycyjne i opcjonalne i działają tak samo:

def fun3(arg1, arg2='b', arg3='c')
    return (arg1, arg2, arg3)

możesz wywołać tę funkcję za pomocą iteracji:

fun3(*[1])
# Returns: (1, 'b', 'c')
fun3(*[1,2,3])
# Returns: (1, 2, 3)

lub tylko ze słownikiem:

fun3(**{'arg1':1})
# Returns: (1, 'b', 'c')
fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
# Returns: (1, 2, 3)

lub możesz użyć obu w tym samym połączeniu:

fun3(*[1,2], **{'arg3':3})
# Returns: (1,2,3)

Uważaj jednak, że nie możesz podać wielu wartości dla tego samego argumentu:

fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'

Rozpakowywanie argumentów funkcji

Jeśli chcesz utworzyć funkcję, która będzie akceptować dowolną liczbę argumentów i nie będzie wymuszać pozycji ani nazwy argumentu w czasie „kompilacji”, jest to możliwe i oto, jak to zrobić:

def fun1(*args, **kwargs):
    print(args, kwargs)

Parametry *args i **kwargs są parametrami specjalnymi ustawionymi odpowiednio na tuple i dict :

fun1(1,2,3)
# Prints: (1, 2, 3) {}
fun1(a=1, b=2, c=3)
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x', 'y', 'z', a=1, b=2, c=3)
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}

Jeśli spojrzysz na wystarczającą ilość kodu w Pythonie, szybko odkryjesz, że jest on powszechnie używany podczas przekazywania argumentów do innej funkcji. Na przykład, jeśli chcesz rozszerzyć klasę ciągów:

class MyString(str):
    def __init__(self, *args, **kwarg):
        print('Constructing MyString')
        super(MyString, self).__init__(*args, **kwarg)


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow