I am trying to implement a custom class which returns a different value when called as list(c) or dict(c). However, it is my impression that both list(c) and dict(c) use c.__iter__() under the hood? If that is the case, how can I get different behaviour calling list(c) and dict(c)? I know that it is possible because Python dictionaries and pandas DataFrames have different hevariours.
For example:
class Foo:
def __init__(self):
self._keys = ['a', 'b', 'd', 'd', 'e']
self._data = [10, 20, 30, 40, 50]
def __iter__(self):
for key, value in zip(self._keys, self._data):
yield key, value
Calling dict(c) I get what I want:
>>> f = Foo()
>>> dict(f)
{'a': 10, 'b': 20, 'd': 40, 'e': 50}
However, I can't get list(c) to print out a list of keys (or values), but instead get both:
>>> f = Foo()
>>> list(f)
[('a', 10), ('b', 20), ('d', 30), ('d', 40), ('e', 50)]
The equivalent code for a dictionary is much cleaner:
>>> f = {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
>>> dict(f)
{'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
>>> list(f)
['a', 'b', 'c', 'd', 'e']
dict(c)does not work property.listanddictcall the same magic methods; there is no way to make a class return something different depending on what called it. I'd suggest that you makekeys()andvalues()methods to return lists.fto be aMappingtype in order to get that sort of behavior. Inheriting fromcollections.Mappingmight be helpful...