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

5 Answers 5

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 :-)

Sign up to request clarification or add additional context in comments.

5 Comments

-1 care to provide an example? I know it's faster, but you haven't actually answered his question, or provided an alternative.
Yes, it will be orders of magnitudes faster.
@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
@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.
@SpencerRathbun If you had posted that, then it WOULD warrant a -1. >;)
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.

Comments

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

Comments

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'

Comments

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',)

1 Comment

If you're going to put just code on a line, indent it four spaces or use the {} button rather than using backticks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.