Reputation: 2837
I wrote the following code:
f = copy.deepcopy(features)
if best_att in features:
f = features.remove(best_att)
where features
is a list of strings and best_att
is a string. Sometimes the code works fine, but sometimes I get the following problem:
If, for example, features = ['outlook', 'temperature', 'humidity', 'wind']
, and best_att = 'outlook'
. When debugging, I see that it enters the if
. However, when trying to preform the remove
, it gets an error: f
is NoneType: None
(i.e., it couldn't find the string in the list).
Any ideas why this happens?
Upvotes: 1
Views: 73
Reputation: 1514
It should be:
f = copy.deepcopy(features)
if best_att in f:
f.remove(best_att)
or
if best_att in features:
features.remove(best_att)
It seems from your code that you want to change the original features
, so just do that. If you want also want a deepcopy f
of it, create that after modifying features
.
You got that message because remove
returns None
: after you assign its return value to f
, that's the value of f
too. In general, Python builtin methods that mutate state "don't return anything" (they return None
) -- they're "all side-effect". The return value is not the mutated object, and it is not a success/failure flag. Some languages draw the distinction between "procedures" and "functions"; these would be "procedures".
If you want to know whether, say, best_att
is in features
, use features.find(best_att)
or features.index(best_att)
.
Upvotes: 3
Reputation: 3307
In python, lists are mutable, which you are probably aware of, since you are using deepcopy
If you call list.remove
on f
, it changes f
and returns None
>>> f = ["spam", "eggs", "harald"]
>>> print(f.remove("harald"))
None
>>> print(f)
["spam", "eggs"]
Upvotes: 1
Reputation: 149776
L.remove
returns None
, which is then assigned to the original list.
help([].remove)
is your friend.
Upvotes: 2