Новый для Python, почему он не цитируется? [Дубликат]

Может быть выполнено с помощью оператора python XOR.

  • Это приведет к удалению дубликатов в каждом списке
  • . Это покажет разницу темп 1 от temp2 и temp2 от temp1.

set(temp1) ^ set(temp2)
651
задан Blaise 2 October 2013 в 15:30
поделиться

10 ответов

Вы можете использовать **kwargs, чтобы ваши функции принимали произвольное количество аргументов ключевого слова («kwargs» означает «аргументы ключевого слова»):

>>> def print_keyword_args(**kwargs):
...     # kwargs is a dict of the keyword args passed to the function
...     for key, value in kwargs.iteritems():
...         print "%s = %s" % (key, value)
... 
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe

Вы также можете использовать синтаксис **kwargs при вызове функций путем построения словаря аргументов ключевого слова и передачи его в вашу функцию:

>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith

Учебник Python содержит хорошее объяснение того, как он работает, а также некоторые приятные примеры.

& lt; - Update ->

Для пользователей, использующих Python 3, вместо iteritems (), используйте пункты ()

738
ответ дан Omkaar.K 22 August 2018 в 03:22
поделиться
  • 1
    Как кто-то, кому понадобилось время, чтобы понять - «kwargs & quot; означает "аргументы ключевых слов" – Gershom Maes 6 May 2015 в 21:42
  • 2
    Для Python 3: обратите внимание, что iteritems() становится items(). – Pintun 30 September 2016 в 15:23

kwargs - это просто словарь, который добавляется к параметрам.

Словарь может содержать пары ключей, значений. И это - кварты. Итак, как это сделать.

Что не так просто.

Например (очень гипотетический) у вас есть интерфейс, который просто вызывает другие процедуры для выполнения задания:

def myDo(what, where, why):
   if what == 'swim':
      doSwim(where, why)
   elif what == 'walk':
      doWalk(where, why)
   ...

Теперь вы получаете новый метод «drive»:

elif what == 'drive':
   doDrive(where, why, vehicle)

Но подождите минуту, появляется новый параметр «автомобиль» - вы этого не знали раньше. Теперь вы должны добавить его в подпись myDo-функции.

Здесь вы можете бросить kwargs в игру - вы просто добавляете kwargs в подпись:

def myDo(what, where, why, **kwargs):
   if what == 'drive':
      doDrive(where, why, **kwargs)
   elif what == 'swim':
      doSwim(where, why, **kwargs)

Таким образом вам не нужно менять подпись функции интерфейса каждый раз, когда некоторые из ваших подпрограмм могут измениться.

Это всего лишь один хороший пример, который вы могли бы найти полезными для kwargs.

58
ответ дан Juergen 22 August 2018 в 03:22
поделиться

Motif: *args и **kwargs служат заполнителем для аргументов, которые необходимо передать вызову функции

, используя *args и **kwargs для вызова функции

def args_kwargs_test(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

Теперь мы будем использовать *args для вызова указанной выше функции

#args can either be a "list" or "tuple"
>>> args = ("two", 3, 5)  
>>> args_kwargs_test(*args)

result:

arg1: two arg2: 3 arg3: 5


Теперь, используя **kwargs для вызова той же функции

#keyword argument "kwargs" has to be a dictionary
>>> kwargs = {"arg3":3, "arg2":'two', "arg1":5}
>>> args_kwargs_test(**kwargs)

result:

arg1: 5 arg2: two arg3: 3

Bottomline: *args не имеет интеллекта, он просто интерполирует переданные аргументы в параметры (в порядке слева направо), в то время как **kwargs ведет себя разумно, помещая соответствующее значение @ в требуемое место

21
ответ дан kmario23 22 August 2018 в 03:22
поделиться
  • kwargs в **kwargs - просто имя переменной. Вы можете очень хорошо иметь **anyVariableName
  • kwargs означает «аргументы ключевого слова». Но я считаю, что их лучше назвать «именованными аргументами», поскольку это просто аргументы, передаваемые вместе с именами (я не считаю какое-либо значение для слова «ключевое слово» в терминах «аргументы ключевых слов». Я думаю, что «ключевое слово» обычно означает слова, зарезервированные по языку программирования и, следовательно, не используемые программистом для имен переменных. В этой ситуации здесь не происходит.). Поэтому мы даем именам param1 и param2 двум значениям параметров, переданным функции следующим образом: func(param1="val1",param2="val2") вместо передачи только значений: func(val1,val2). Таким образом, я считаю, что их следует соответствующим образом называть «произвольным числом именованных аргументов», поскольку мы можем указать любое количество этих параметров (то есть аргументы), если func имеет подпись func(**kwargs)

Так что, говоря, что позвольте мне сначала объяснить «именованные аргументы», а затем «произвольное число именованных аргументов» kwargs.

Именованные аргументы

  • named args должны следовать позиционным args
  • порядок названных аргументов не важен
  • Пример
    def function1(param1,param2="arg2",param3="arg3"):
        print("\n"+str(param1)+" "+str(param2)+" "+str(param3)+"\n")
    
    function1(1)                      #1 arg2 arg3   #1 positional arg
    function1(param1=1)               #1 arg2 arg3   #1 named arg
    function1(1,param2=2)             #1 2 arg3      #1 positional arg, 1 named arg
    function1(param1=1,param2=2)      #1 2 arg3      #2 named args       
    function1(param2=2, param1=1)     #1 2 arg3      #2 named args out of order
    function1(1, param3=3, param2=2)  #1 2 3         #
    
    #function1()                      #invalid: required argument missing
    #function1(param2=2,1)            #invalid: SyntaxError: non-keyword arg after keyword arg
    #function1(1,param1=11)           #invalid: TypeError: function1() got multiple values for argument 'param1'
    #function1(param4=4)              #invalid: TypeError: function1() got an unexpected keyword argument 'param4'
    

Произвольное число именованных аргументов kwargs

  • Последовательность параметров функции: формальные параметры позиционного параметра, фиксирующие произвольное количество аргументов (с префиксом *) с формальными параметрами формальных параметров, фиксирующими произвольное количество именованных параметров (с префиксом **)
  • Пример
    def function2(param1, *tupleParams, param2, param3, **dictionaryParams):
        print("param1: "+ param1)
        print("param2: "+ param2)
        print("param3: "+ param3)
        print("custom tuple params","-"*10)
        for p in tupleParams:
            print(str(p) + ",")
        print("custom named params","-"*10)
        for k,v in dictionaryParams.items():
            print(str(k)+":"+str(v))
    
    function2("arg1",
              "custom param1",
              "custom param2",
              "custom param3",
              param3="arg3",
              param2="arg2", 
              customNamedParam1 = "val1",
              customNamedParam2 = "val2"
              )
    
    # Output
    #
    #param1: arg1
    #param2: arg2
    #param3: arg3
    #custom tuple params ----------
    #custom param1,
    #custom param2,
    #custom param3,
    #custom named params ----------
    #customNamedParam2:val2
    #customNamedParam1:val1
    

Передача кортежей и переменных dict для пользовательских аргументов

Чтобы закончить его, позвольте мне также отметить, что мы можем пройти

  • ", фиксирующий произвольное число ar guments "в качестве переменной tuple и
  • " формальный параметр, фиксирующий произвольное количество именованных параметров "в качестве переменной dict

Таким образом, тот же самый вызов можно сделать следующим образом:

tupleCustomArgs = ("custom param1", "custom param2", "custom param3")
dictCustomNamedArgs = {"customNamedParam1":"val1", "customNamedParam2":"val2"}

function2("arg1",
      *tupleCustomArgs,    #note *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs     #note **
      )

Наконец, обратите внимание на * и ** в вызовах функций выше. Если мы их опустим, мы можем получить больные результаты.

Опускание * в кортежах args:

function2("arg1",
      tupleCustomArgs,   #omitting *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs
      )

печатает

param1: arg1
param2: arg2
param3: arg3
custom tuple params ----------
('custom param1', 'custom param2', 'custom param3'),
custom named params ----------
customNamedParam2:val2
customNamedParam1:val1

Выше кортежа ('custom param1', 'custom param2', 'custom param3') печатается как есть.

Опускание dict args:

function2("arg1",
      *tupleCustomArgs,   
      param3="arg3",
      param2="arg2", 
      dictCustomNamedArgs   #omitting **
      )

дает

dictCustomNamedArgs
         ^
SyntaxError: non-keyword arg after keyword arg
16
ответ дан Mahesha999 22 August 2018 в 03:22
поделиться
  • 1
    Я бы предположил, что терминология keyword исходит из того факта, что вы передаете в dict, который является базой данных пар ключ-значение. – crobar 11 May 2017 в 09:38
  • 2
    вы имеете в виду слово «ключ» в словах «ключ»? Также его обычно не называют базой данных, а словарем. Но все еще не в состоянии найти какое-либо значение для использования слова «ключевое слово». – Mahesha999 11 May 2017 в 12:50

На основании того, что хороший образец иногда лучше длинного дискурса, я напишу две функции, используя все объекты передачи аргументов переменной python (как позиционные, так и именованные аргументы). Вы можете легко увидеть, что он делает сам:

def f(a = 0, *args, **kwargs):
    print("Received by f(a, *args, **kwargs)")
    print("=> f(a=%s, args=%s, kwargs=%s" % (a, args, kwargs))
    print("Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)")
    g(10, 11, 12, *args, d = 13, e = 14, **kwargs)

def g(f, g = 0, *args, **kwargs):
    print("Received by g(f, g = 0, *args, **kwargs)")
    print("=> g(f=%s, g=%s, args=%s, kwargs=%s)" % (f, g, args, kwargs))

print("Calling f(1, 2, 3, 4, b = 5, c = 6)")
f(1, 2, 3, 4, b = 5, c = 6)

И вот вывод:

Calling f(1, 2, 3, 4, b = 5, c = 6)
Received by f(a, *args, **kwargs) 
=> f(a=1, args=(2, 3, 4), kwargs={'c': 6, 'b': 5}
Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
Received by g(f, g = 0, *args, **kwargs)
=> g(f=10, g=11, args=(12, 2, 3, 4), kwargs={'c': 6, 'b': 5, 'e': 14, 'd': 13})
41
ответ дан Martlark 22 August 2018 в 03:22
поделиться

Распаковка словарей

** распаковывает словари.

Это

func(a=1, b=2, c=3)

совпадает с

args = {'a': 1, 'b': 2, 'c':3}
func(**args)

Это полезно, если вам нужно построить параметры:

args = {'name': person.name}
if hasattr(person, "address"):
    args["address"] = person.address
func(**args)  # either expanded to func(name=person.name) or
              #                    func(name=person.name, address=person.address)

Параметры упаковки для функции

def setstyle(**styles):
    for key, value in styles.iteritems():      # styles is a regular dictionary
        setattr(someobject, key, value)

Это позволяет использовать такую ​​функцию:

setstyle(color="red", bold=False)
278
ответ дан Mathias Müller 22 August 2018 в 03:22
поделиться
  • 1
    kwarg - это просто имя переменной? поэтому я могу использовать def func (** args): и это работает wud? – Sriram 8 June 2011 в 14:02
  • 2
    @ Шририм: Верно. Звездочки важны. kwargs - это просто имя, которое дает, если нет лучшего. (Обычно есть.) – Georg Schölly 8 June 2011 в 17:46
  • 3
    @Sriram: для удобства чтения вы должны придерживаться kwargs - другие оценщики оценят это. – johndodo 21 March 2012 в 12:27
  • 4
    ** do unpack dictionaries. & gt; ум взорван / конечно! +1 для объяснения этого бита. – Marc 13 March 2015 в 04:16
  • 5
    Примечание: .iteritems() было переименовано в .items() в Python 3. – fnkr 17 September 2015 в 07:41

Вот простая функция, которая объясняет использование:

def print_wrap(arg1, *args, **kwargs):
    print(arg1)
    print(args)
    print(kwargs)
    print(arg1, *args, **kwargs)

Любые аргументы, которые не , указанные в определении функции, будут помещены в список args , или kwargs, в зависимости от того, являются ли они аргументами ключевого слова или нет:

>>> print_wrap('one', 'two', 'three', end='blah', sep='--')
one
('two', 'three')
{'end': 'blah', 'sep': '--'}
one--two--threeblah

Если вы добавите аргумент ключевого слова, который никогда не будет передан функции, будет поднята ошибка:

>>> print_wrap('blah', dead_arg='anything')
TypeError: 'dead_arg' is an invalid keyword argument for this function
5
ответ дан naught101 22 August 2018 в 03:22
поделиться

В качестве дополнения вы также можете смешивать различные способы использования при вызове функций kwargs:

def test(**kwargs):
    print kwargs['a']
    print kwargs['b']
    print kwargs['c']


args = { 'b': 2, 'c': 3}

test( a=1, **args )

дает этот вывод:

1
2
3

Обратите внимание, что ** kwargs имеет быть последним аргументом

9
ответ дан philipp 22 August 2018 в 03:22
поделиться

kwargs являются синтаксическим сахаром для передачи аргументов имени в виде словарей (для func) или словарей в качестве именных аргументов (для func)

5
ответ дан user 22 August 2018 в 03:22
поделиться

Вот пример, который, я надеюсь, полезен:

#! /usr/bin/env python
#
def g( **kwargs) :
  print ( "In g ready to print kwargs" )
  print kwargs
  print ( "in g, calling f")
  f ( **kwargs )
  print ( "In g, after returning from f")

def f( **kwargs ) :
  print ( "in f, printing kwargs")
  print ( kwargs )
  print ( "In f, after printing kwargs")


g( a="red", b=5, c="Nassau")

g( q="purple", w="W", c="Charlie", d=[4, 3, 6] )

Когда вы запустите программу, вы получите:

$ python kwargs_demo.py 
In g ready to print kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
in g, calling f
in f, printing kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
In f, after printing kwargs
In g, after returning from f
In g ready to print kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
in g, calling f
in f, printing kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
In f, after printing kwargs
In g, after returning from f

Ключ отнимает здесь то, что переменное число именованных аргументов в вызове переводится в словарь в функции.

1
ответ дан user1928764 22 August 2018 в 03:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: