17

I look up in a table if keys have associated arrays, or not. By design, my table.__getitem__() somtimes returns None rather than KeyError-s. I would like this value to be either None, or the numpy array associated with w.

value = table[w] or table[w.lower()]
# value should be a numpy array, or None
if value is not None:
    stack = np.vstack((stack, value))

Only if I go with the above code, and the first lookup is a match, I get :

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

and if I go with value = table[w].any() or table[w.lower()].any(), then if it's a mismatch, I expectedly bump into :

AttributeError: 'NoneType' object has no attribute 'any'

I must be missing the correct way to do this, how to do ?

5
  • 1
    Obvious repost of this other question, because the correct answer there doesn't satisfy my need. I'd want a shorter way than if table[w] is not None: ... elif table[w.lower()] is not None: ... else, if possible. Commented Sep 19, 2016 at 7:20
  • @Goyo: v = a or b raises the ValueError if a is an array (not if a is None and b is an array though) Commented Sep 19, 2016 at 7:29
  • a = None .... isinstance(a, (type(None))) # True .... if a is anything else, it will return false. Obviously only useful to branch between None and if you can guarantee that 'a' will be some incarnation of an array Commented Sep 19, 2016 at 7:40
  • @Nikana Your question is not clear. " I would like this value to be either None..." when do you want it to be None? "or the numpy array associated with w" What's the associated array? table[w]? table[w.lower()]? The errors you are getting are to be expected but I do not understand what you want to achieve. Commented Sep 19, 2016 at 7:40
  • @Goyo: I want value to be None if table returns none on w, and none on w.lower(). Else, to be the first non-None value (so yes, ideally, table[w]). Commented Sep 19, 2016 at 7:42

5 Answers 5

14
if type(value) is numpy.ndarray:
    #do numpy things
else
    # Handle None

Though the above would work, I would suggest to keep signatures simple and consistent, ie table[w] should always return numpy array. In case of None, return empty array.

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

1 Comment

so do I have one such block with w and another with w.lower() ? that's quite verbose, isn't it ?
8

The question is answered, but other folks who encounter this error may want a general solution. With the idea of being explicit in mind we can use the function isinstance. Here is a working example.

import numpy as np

a = np.array([1,2,3])
b = None
for itm in [a,b]:
    isinstance(itm,np.ndarray)

So in the context of the question

value = table[w]
if not isinstance(value,np.ndarray):
    value = table[w.lower()]

4 Comments

Sorry but this has very little to do with the question. The question is about the value = ??? part.
This is the same answer as your accepted answer just more explicit. The problem is that you cannot check to see if an array == None (the error you observed). But you can use the is instance that I showed above. I edited the above comment.
I can very much check if value == None, that's what the accepted answer does. What I would have loved is a one liner that assigns the first non-None value out of [table[w], table[w.lower()]] if any, or else None. The accepted answer does that perfectly, in 3 lines. I don't understand your contribution.
using is works in this case, but using == throws the ValueError you saw above. Good Python code is explicit. I am showing you how to test if value is an array not if it is None... which is better Python code. I refer you to the Zen of Python if this is still hard to understand.
4

IIUC this should work:

value = table[w]
if value is None:
    value = table[w.lower()]

Comments

2

Use dict.get.

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

value = table.get(w, table.get(w.lower()))

So if table[w] is not there you will get table[w.lower()] and if that's not there you'll get None.

4 Comments

Ooh, interesting. Though... what happens if the default value is None, does it fail, or accept that ? And why would it default to the default if the first does return something, i.e. None ?
@NikanaReklawyks Every function in Python implicitly returns None if nothing else is specified: the default value is what is assigned if the first returns None
Note that OP mentioned that their __getitem__ implementation won't always raise a KeyError. Also table.get(w.lower()) won't be lazily evaluated.
OP says it sometimes returns None instead of KeyError so I assumed table is just a normal dict filled with numpy arrays and Nones. But good point on the laziness.
0

Use the type operator!

if type(a) == type(None):
    # it's None
else:
    # it's something else, possible a numpy matrix

Comments

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.