2

In my code I have the following:

if all(requiredField in submittedFields for requiredField in requiredFields):
    # all required fields in submittedFields exist
else:
    # error handling

The goal is to check if a list of strings in requiredFields are all present in submittedFields

This works fine when requiredFields is a list of strings with length > 1. But, when you have something like

requiredFields = ('single element')

Then the for loop iterates over each character instead of the string itself.

So my question is, is there a more pythonic means of handling this other than

try: 
    requiredFields.sort()
    # requiredFields is a list of strings
except AttributeError:
    # requiredFields is a string list whose length == 1
Scott Tomaszewski
  • 1,009
  • 8
  • 27

5 Answers5

6

Using python sets would be much more efficient:

submitted_fields = set(['length', 'width', 'color', 'single element'])
required_fields = set(['width', 'length'])
if submitted_fields >= required_fields:
    # all required fields in submittedFields exist
else:
    # error handling

Several optimizations make this fast:

  • The hash table implementation of sets ensures a high likelihood of a match before doing a character by character equality test.
  • If two strings are identical (the same object in memory), the identity check will bypass a character-by-character equality check.

Note. It looks like your original problem was with tuple notation. Steven Rumbalski addressed that very well. Of course, if you use sets, this becomes a non-issue.

Good luck with your field validation :-)

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • -1 care to provide an example? I know it's faster, but you haven't actually answered his question, or provided an alternative. – Spencer Rathbun Nov 23 '11 at 19:52
  • Yes, it will be orders of magnitudes faster. –  Nov 23 '11 at 19:52
  • @SpencerRathbun While not immediately obvious, it does answer the question. Specifically the "is there a more pythonic means of handling this" bit. The question is what one would call an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Shawn Chin Nov 23 '11 at 19:56
  • @ShawnChin True, but I could just as easily say that "a more efficient solution would be to write a function in assembler. This is left as an exercise to the reader..." Which is why I gave him the -1. Since he added an example, I'm changing that to a +1. – Spencer Rathbun Nov 23 '11 at 20:23
  • @SpencerRathbun If you had posted that, then it WOULD warrant a -1. >;) – Shawn Chin Nov 23 '11 at 20:27
5

A string enclosed in parenthesis is not a tuple -- it's a string. To make a one item tuple you need a trailing comma:

>>> ('single element') # this is not a tuple, it's a string
'single element'
>>> ('single element',) # note the trailing comma
('single element',)

For more info see the wiki on Tuple Syntax the Stack Overflow question Python tuple comma syntax rule.

Community
  • 1
  • 1
Steven Rumbalski
  • 44,786
  • 9
  • 89
  • 119
0

This happens because the definition

requiredFields = ('single element')

is actually equivalent to

requiredFields = 'single element'

To make a single element list, do

requiredFields = ['single element']

To make a single element tuple, do

requiredFields = ('single element',)
agf
  • 171,228
  • 44
  • 289
  • 238
infrared
  • 3,566
  • 2
  • 25
  • 37
  • If you're going to put just code on a line, indent it four spaces or use the `{}` button rather than using backticks. – agf Apr 21 '12 at 14:45
0

first of all you should never have requiredFields = ('single element') -- if you want a tuple you should write requiredFields = ('single element',).

but assuming you don't have control over your input, the most pythonic way to test is:

if isinstance(requiredFields, basestring):
    # requiredFields is a string
else:
    # requiredFields is iterable
simon
  • 15,344
  • 5
  • 45
  • 67
0

Why don't you just do something like this:

required = ['name', 'password']
submitted = ['name', 'email']

for field in required:
    if field not in submitted:
        print field + ' is required'
icirellik
  • 746
  • 6
  • 21