0

is it possible to do things like this:

def f():
  d={}
  d[1]='qwe'
  d[2]='rty'
  return d

a,b=f()[1:2]

not a,b=f()[1],f()[2] and not

t=f()
a,b=t[1],t[2]

I wont avoid extra lines and call function only once.

2
  • 1
    Are the keys you use for indexing actually sequential integers like 1 and 2? (If yes, use lists). Commented Oct 6, 2012 at 16:41
  • Is the order of the items relevant for you? Commented Oct 6, 2012 at 16:42

3 Answers 3

2

It's unclear to me what it is exactly you want to do. You're indexing a dictionary by integers. Integers can be used as keys to a dictionary just fine, but it looks like a list would make more sense in your case. An important difference between dictionaries and lists is that dicts are not ordered. d[1] and d[2] will not necessarily be in first and second place in your example. So if you depend on the order, standard dictionaries won't work anyway (an OrderedDict would).

(The fact that your data structure is returned by a function f() doesn't make any difference here, so I'll ignore it for better readability)

If you got

lst = ['qwe', 'rty']

you can simply do

a, b = lst

to assign lst[0] to a, and lst[1] to b. Lists can also be sliced:

long_lst = range(1000)
a, b = long_lst[500:502]

If you actually do want do use a dictionary, you can access its components like this:

>>> d = {'a': 'AAA', 'b': 'BBB'}
>>> d.keys()
['a', 'b']
>>> d.values()
['AAA', 'BBB']
>>> d.items()
[('a', 'AAA'), ('b', 'BBB')]

But as stated above, even if they happen to be in the right order in this example, you can't rely on the order of a dictionary, it will change over time.

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

Comments

1

No; dictionary indexing doesn't support slicing, since it usually doesn't make any sense in dictionary keys.

You can roll it yourself, though, with something like

a, b = map(f().get, [1, 2])

or (thanks @DSM)

a, b = operator.itemgetter(1, 2)(f())

These are slightly different in that if the result of f() is missing 1 or 2 as keys, the first will default to assigning None and the second will raise KeyError. map(f().__getitem__, ...) should be equivalent to itemgetter, though probably slightly slower.

1 Comment

Alternatively, itemgetter(1,2)(f()).
1

Yes, just use method dict.values():

x,y = f().values()[0:2]

2 Comments

You can't rely on the order of values though.
@Dougal yes, you're right: Python documentation: docs.python.org/library/stdtypes.html#dict.items : "Keys and values are listed in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions" but "If items(), keys(), values(), iteritems(), iterkeys(), and itervalues() are called with no intervening modifications to the dictionary, the lists will directly correspond"

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.