Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #83443 > unrolled thread
| Started by | Adam Funk <a24061@ducksburg.com> |
|---|---|
| First post | 2015-01-09 14:44 +0000 |
| Last post | 2015-01-26 13:43 +0000 |
| Articles | 14 — 8 participants |
Back to article view | Back to comp.lang.python
Why does argparse return None instead of [] if an append action isn't used? Adam Funk <a24061@ducksburg.com> - 2015-01-09 14:44 +0000
Re: Why does argparse return None instead of [] if an append action isn't used? Skip Montanaro <skip.montanaro@gmail.com> - 2015-01-09 08:57 -0600
Re: Why does argparse return None instead of [] if an append action isn't used? Adam Funk <a24061@ducksburg.com> - 2015-01-09 15:25 +0000
Re: Why does argparse return None instead of [] if an append action isn't used? Ned Batchelder <ned@nedbatchelder.com> - 2015-01-09 10:12 -0500
Re: Why does argparse return None instead of [] if an append action isn't used? Adam Funk <a24061@ducksburg.com> - 2015-01-26 13:43 +0000
Re: Why does argparse return None instead of [] if an append action isn't used? Peter Otten <__peter__@web.de> - 2015-01-26 15:04 +0100
Re: Why does argparse return None instead of [] if an append action isn't used? Adam Funk <a24061@ducksburg.com> - 2015-01-26 15:50 +0000
Re: Why does argparse return None instead of [] if an append action isn't used? Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-26 09:13 -0700
Re: Why does argparse return None instead of [] if an append action isn't used? Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2015-01-26 18:29 +0200
Re: Why does argparse return None instead of [] if an append action isn't used? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-01-26 17:18 +0000
Re: Why does argparse return None instead of [] if an append action isn't used? Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-26 11:23 -0700
Re: Why does argparse return None instead of [] if an append action isn't used? Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-26 11:26 -0700
Re: Why does argparse return None instead of [] if an append action isn't used? Wolfgang Maier <wolfgang.maier@biologie.uni-freiburg.de> - 2015-01-09 16:50 +0100
Re: Why does argparse return None instead of [] if an append action isn't used? Adam Funk <a24061@ducksburg.com> - 2015-01-26 13:43 +0000
| From | Adam Funk <a24061@ducksburg.com> |
|---|---|
| Date | 2015-01-09 14:44 +0000 |
| Subject | Why does argparse return None instead of [] if an append action isn't used? |
| Message-ID | <l265obxc6d.ln2@news.ducksburg.com> |
I noticed in use that if an option with the 'append' action isn't
used, argparse assigns None to it rather than an empty list, &
confirmed this interactively:
#v+
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
_AppendAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--bar', action='append')
_AppendAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(bar=None, foo=['1', '2'])
#v-
This makes it a bit more trouble to use:
if options.bar:
for b in options:bar
do_stuff(b)
instead of
for b in options.bar
do_stuff(b)
which is (of course) what I was doing when I discovered the None. Is
there any benefit to the user from this, or is it just an "accident"
of the way argparse is written?
--
The history of the world is the history of a privileged few.
--- Henry Miller
[toc] | [next] | [standalone]
| From | Skip Montanaro <skip.montanaro@gmail.com> |
|---|---|
| Date | 2015-01-09 08:57 -0600 |
| Message-ID | <mailman.17527.1420815432.18130.python-list@python.org> |
| In reply to | #83443 |
> I noticed in use that if an option with the 'append' action isn't > used, argparse assigns None to it rather than an empty list, & > confirmed this interactively: I don't use argparse (or optparse), being a getopt Luddite myself, but can you set the default for an action in the add_argument call? Skip
[toc] | [prev] | [next] | [standalone]
| From | Adam Funk <a24061@ducksburg.com> |
|---|---|
| Date | 2015-01-09 15:25 +0000 |
| Message-ID | <7h85obxhje.ln2@news.ducksburg.com> |
| In reply to | #83444 |
On 2015-01-09, Skip Montanaro wrote:
>> I noticed in use that if an option with the 'append' action isn't
>> used, argparse assigns None to it rather than an empty list, &
>> confirmed this interactively:
>
> I don't use argparse (or optparse), being a getopt Luddite myself, but
> can you set the default for an action in the add_argument call?
Well, duh! That works, thanks. (I can't explain why I didn't think
of that.)
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append',default=[])
_AppendAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=[], type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--bar', action='append',default=[])
_AppendAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=[], type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(bar=[], foo=['1', '2'])
>>> parser.parse_args('--foo 1 --bar 2'.split())
Namespace(bar=['2'], foo=['1'])
>>> parser.parse_args([])
Namespace(bar=[], foo=[])
--
Slade was the coolest band in England. They were the kind of guys
that would push your car out of a ditch. --- Alice Cooper
[toc] | [prev] | [next] | [standalone]
| From | Ned Batchelder <ned@nedbatchelder.com> |
|---|---|
| Date | 2015-01-09 10:12 -0500 |
| Message-ID | <mailman.17529.1420816664.18130.python-list@python.org> |
| In reply to | #83443 |
On 1/9/15 9:44 AM, Adam Funk wrote:
> This makes it a bit more trouble to use:
>
> if options.bar:
> for b in options:bar
> do_stuff(b)
>
> instead of
>
> for b in options.bar
> do_stuff(b)
This doesn't answer why the value defaults to None, and some people may
recoil at it, but I've used:
for b in options.bar or ():
do_stuff(b)
--
Ned Batchelder, http://nedbatchelder.com
[toc] | [prev] | [next] | [standalone]
| From | Adam Funk <a24061@ducksburg.com> |
|---|---|
| Date | 2015-01-26 13:43 +0000 |
| Message-ID | <8tshpbxjvv.ln2@news.ducksburg.com> |
| In reply to | #83449 |
On 2015-01-09, Ned Batchelder wrote:
> On 1/9/15 9:44 AM, Adam Funk wrote:
>> This makes it a bit more trouble to use:
>>
>> if options.bar:
>> for b in options:bar
>> do_stuff(b)
>>
>> instead of
>>
>> for b in options.bar
>> do_stuff(b)
>
> This doesn't answer why the value defaults to None, and some people may
> recoil at it, but I've used:
>
> for b in options.bar or ():
> do_stuff(b)
Do you mean "for b in options.bar or []:" ?
--
War is God's way of teaching Americans geography.
[Ambrose Bierce]
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-01-26 15:04 +0100 |
| Message-ID | <mailman.18148.1422281105.18130.python-list@python.org> |
| In reply to | #84598 |
Adam Funk wrote: > On 2015-01-09, Ned Batchelder wrote: > >> On 1/9/15 9:44 AM, Adam Funk wrote: >>> This makes it a bit more trouble to use: >>> >>> if options.bar: >>> for b in options:bar >>> do_stuff(b) >>> >>> instead of >>> >>> for b in options.bar >>> do_stuff(b) >> >> This doesn't answer why the value defaults to None, and some people may >> recoil at it, but I've used: >> >> for b in options.bar or (): >> do_stuff(b) > > Do you mean "for b in options.bar or []:" ? Doesn't matter; in the context of a for loop any empty iterable would do.
[toc] | [prev] | [next] | [standalone]
| From | Adam Funk <a24061@ducksburg.com> |
|---|---|
| Date | 2015-01-26 15:50 +0000 |
| Message-ID | <ta4ipbx9j3.ln2@news.ducksburg.com> |
| In reply to | #84600 |
On 2015-01-26, Peter Otten wrote:
> Adam Funk wrote:
>
>> On 2015-01-09, Ned Batchelder wrote:
>>
>>> On 1/9/15 9:44 AM, Adam Funk wrote:
>>>> This makes it a bit more trouble to use:
>>>>
>>>> if options.bar:
>>>> for b in options:bar
>>>> do_stuff(b)
>>>>
>>>> instead of
>>>>
>>>> for b in options.bar
>>>> do_stuff(b)
>>>
>>> This doesn't answer why the value defaults to None, and some people may
>>> recoil at it, but I've used:
>>>
>>> for b in options.bar or ():
>>> do_stuff(b)
>>
>> Do you mean "for b in options.bar or []:" ?
>
> Doesn't matter; in the context of a for loop any empty iterable would do.
Of course it would. Doh!
--
A recent study conducted by Harvard University found that the average
American walks about 900 miles a year. Another study by the AMA found
that Americans drink, on average, 22 gallons of alcohol a year. This
means, on average, Americans get about 41 miles to the gallon.
http://www.cartalk.com/content/average-americans-mpg
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-01-26 09:13 -0700 |
| Message-ID | <mailman.18151.1422288861.18130.python-list@python.org> |
| In reply to | #84605 |
On Mon, Jan 26, 2015 at 8:50 AM, Adam Funk <a24061@ducksburg.com> wrote: > On 2015-01-26, Peter Otten wrote: > >> Adam Funk wrote: >> >>> On 2015-01-09, Ned Batchelder wrote: >>>> for b in options.bar or (): >>>> do_stuff(b) >>> >>> Do you mean "for b in options.bar or []:" ? >> >> Doesn't matter; in the context of a for loop any empty iterable would do. > > Of course it would. Doh! Stylistically, I generally prefer the empty list for this. The empty tuple might be a little faster since it's a singleton and doesn't need to be constructed at runtime, but that's clearly a micro-optimization, and I think the list more accurately conveys the intention of "something to be iterated over". Although tuples are iterable, I don't often use them for that purpose.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jpiitula@ling.helsinki.fi> |
|---|---|
| Date | 2015-01-26 18:29 +0200 |
| Message-ID | <qotioft4iao.fsf@ruuvi.it.helsinki.fi> |
| In reply to | #84606 |
Ian Kelly writes: > On Mon, Jan 26, 2015 at 8:50 AM, Adam Funk wrote: > > On 2015-01-26, Peter Otten wrote: > > > >> Adam Funk wrote: > >> > >>> On 2015-01-09, Ned Batchelder wrote: > >>>> for b in options.bar or (): > >>>> do_stuff(b) > >>> > >>> Do you mean "for b in options.bar or []:" ? > >> > >> Doesn't matter; in the context of a for loop any empty iterable > >> would do. > > > > Of course it would. Doh! > > Stylistically, I generally prefer the empty list for this. The empty > tuple might be a little faster since it's a singleton and doesn't > need to be constructed at runtime, but that's clearly a > micro-optimization, and I think the list more accurately conveys the > intention of "something to be iterated over". Although tuples are > iterable, I don't often use them for that purpose. I've used tuples to convey the intention of immutability, as opposed to using lists. For all I know, collecting a generator (from groupby) into a tuple might be slower than collecting it into a list. I have no intention to measure this. The programs have been fast enough for me.
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-01-26 17:18 +0000 |
| Message-ID | <mailman.18153.1422292702.18130.python-list@python.org> |
| In reply to | #84607 |
On 26/01/2015 16:29, Jussi Piitulainen wrote: > > I've used tuples to convey the intention of immutability, as opposed > to using lists. For all I know, collecting a generator (from groupby) > into a tuple might be slower than collecting it into a list. I have no > intention to measure this. The programs have been fast enough for me. > IIRC, and probably from this list, creating tuples is way faster than creating lists, but accessing items is slower. Can anybody confirm this for us? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-01-26 11:23 -0700 |
| Message-ID | <mailman.18155.1422296665.18130.python-list@python.org> |
| In reply to | #84607 |
On Mon, Jan 26, 2015 at 10:18 AM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote: > IIRC, and probably from this list, creating tuples is way faster than > creating lists, but accessing items is slower. Can anybody confirm this for > us? The first seems to be true as long as the tuples are small. $ python3 -m timeit 't = (1000, 2000, 3000)' 100000000 loops, best of 3: 0.0147 usec per loop $ python3 -m timeit 't = [1000, 2000, 3000]' 10000000 loops, best of 3: 0.0678 usec per loop $ python3 -m timeit 't = tuple(range(10000))' 10000 loops, best of 3: 183 usec per loop $ python3 -m timeit 't = list(range(10000))' 10000 loops, best of 3: 174 usec per loop $ python3 -m timeit 't = tuple(range(10000000))' 10 loops, best of 3: 323 msec per loop $ python3 -m timeit 't = list(range(10000000))' 10 loops, best of 3: 306 msec per loop This is probably a result of the use of freelists to avoid reallocating the tuple objects, though. I don't see any substantial difference in access time: $ python3 -m timeit -s 't = tuple(range(10000))' 't[5000]' 10000000 loops, best of 3: 0.0316 usec per loop $ python3 -m timeit -s 't = list(range(10000))' 't[5000]' 10000000 loops, best of 3: 0.0318 usec per loop $ python3 -m timeit -s 't = tuple(range(10000))' 'for x in t: pass' 10000 loops, best of 3: 112 usec per loop $ python3 -m timeit -s 't = list(range(10000))' 'for x in t: pass' 10000 loops, best of 3: 113 usec per loop
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-01-26 11:26 -0700 |
| Message-ID | <mailman.18156.1422296837.18130.python-list@python.org> |
| In reply to | #84607 |
On Mon, Jan 26, 2015 at 11:23 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote: > $ python3 -m timeit 't = (1000, 2000, 3000)' > 100000000 loops, best of 3: 0.0147 usec per loop > $ python3 -m timeit 't = [1000, 2000, 3000]' > 10000000 loops, best of 3: 0.0678 usec per loop > $ python3 -m timeit 't = tuple(range(10000))' > 10000 loops, best of 3: 183 usec per loop > $ python3 -m timeit 't = list(range(10000))' > 10000 loops, best of 3: 174 usec per loop > $ python3 -m timeit 't = tuple(range(10000000))' > 10 loops, best of 3: 323 msec per loop > $ python3 -m timeit 't = list(range(10000000))' > 10 loops, best of 3: 306 msec per loop > > This is probably a result of the use of freelists to avoid > reallocating the tuple objects, though. I don't see any substantial > difference in access time: Whoops. Actually it's a result of the 3-element tuple being a constant in the code object. If we use the constructor, the difference mostly goes away. $ python3 -m timeit 't = tuple(range(1000, 4000, 1000))' 1000000 loops, best of 3: 0.559 usec per loop $ python3 -m timeit 't = list(range(1000, 4000, 1000))' 1000000 loops, best of 3: 0.585 usec per loop
[toc] | [prev] | [next] | [standalone]
| From | Wolfgang Maier <wolfgang.maier@biologie.uni-freiburg.de> |
|---|---|
| Date | 2015-01-09 16:50 +0100 |
| Message-ID | <mailman.17532.1420818709.18130.python-list@python.org> |
| In reply to | #83443 |
On 01/09/2015 03:44 PM, Adam Funk wrote:
> I noticed in use that if an option with the 'append' action isn't
> used, argparse assigns None to it rather than an empty list, &
> confirmed this interactively:
>
> #v+
>>>> import argparse
>>>> parser = argparse.ArgumentParser()
>>>> parser.add_argument('--foo', action='append')
> _AppendAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>>> parser.add_argument('--bar', action='append')
> _AppendAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>>> parser.parse_args('--foo 1 --foo 2'.split())
> Namespace(bar=None, foo=['1', '2'])
> #v-
>
Isn't that the exact behaviour documented here:
https://docs.python.org/3/library/argparse.html#default
where it says that the default for the default argument is None ?
I think Skip is right: you should be able to just add
default = []
to your arguments in the add_argument call.
Wolfgang
[toc] | [prev] | [next] | [standalone]
| From | Adam Funk <a24061@ducksburg.com> |
|---|---|
| Date | 2015-01-26 13:43 +0000 |
| Message-ID | <msshpbxjvv.ln2@news.ducksburg.com> |
| In reply to | #83453 |
On 2015-01-09, Wolfgang Maier wrote:
> On 01/09/2015 03:44 PM, Adam Funk wrote:
>> I noticed in use that if an option with the 'append' action isn't
>> used, argparse assigns None to it rather than an empty list, &
>> confirmed this interactively:
>>
>> #v+
>>>>> import argparse
>>>>> parser = argparse.ArgumentParser()
>>>>> parser.add_argument('--foo', action='append')
>> _AppendAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>>>> parser.add_argument('--bar', action='append')
>> _AppendAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>>>> parser.parse_args('--foo 1 --foo 2'.split())
>> Namespace(bar=None, foo=['1', '2'])
>> #v-
>>
>
> Isn't that the exact behaviour documented here:
>
> https://docs.python.org/3/library/argparse.html#default
>
> where it says that the default for the default argument is None ?
>
> I think Skip is right: you should be able to just add
>
> default = []
>
> to your arguments in the add_argument call.
Yes, it works.
--
Master Foo said: "A man who mistakes secrets for knowledge is like
a man who, seeking light, hugs a candle so closely that he smothers
it and burns his hand." --- Eric Raymond
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web