3

My code looks like this:

if query.orderby:
    for q in query.orderby:
        if 'severity' in q:

Note: query.orderby is a list of dict. Looks something like [{"severity": "asc"},{"name": "desc"}] How can i optimize these lines? Is there any way to replace the for loop and still get same functionality as the code above?

NSP
  • 1,193
  • 4
  • 15
  • 26
  • what logic in if statement? – Andriy Ivaneyko Jun 09 '16 at 08:58
  • [What does "list comprehension" in Python mean? How does it work and how can I use it?](http://stackoverflow.com/q/34835951) – Bhargav Rao Jun 09 '16 at 08:58
  • 3
    It depends on what you want to do after last `if`. – Mazdak Jun 09 '16 at 08:58
  • Basically if the key 'severity' is present, i alter its value and sort the array items based on the key value – NSP Jun 09 '16 at 09:01
  • You wrote "query.orderby is a list of dict". If `query` always has an attribute `.orderby` then your first `if` (`if query.orderby:`) is superflous. Otherwise, your `for` loop followed by an `if` is, at least in my opinion, as good as a more complex solution that iterates on a filtered version of `query.orderby`, e.g., `for q in (q in query.orderby if 'severity' in q)` — your present implementation (modulo the first `if`, that could be removed) adds a level of indentation but expresses in a more clean way your purpose – gboffi Jun 09 '16 at 09:13
  • Thanks @gboffi. orderby need not be present always.That's the reason ive added the first `if` clause – NSP Jun 09 '16 at 09:19
  • OK, so your code is as good as it can be... – gboffi Jun 09 '16 at 09:21
  • @gboffi thanks for the help. – NSP Jun 09 '16 at 09:23
  • @sanjana I think you can remove your first if statement. – Hassan Mehmood Jun 09 '16 at 09:40
  • I've changed my mind, if the `orderby` attribute is optional, you have a problem with a bare `if`... see my answer below. Ciao – gboffi Jun 09 '16 at 09:45

4 Answers4

1

It's hard to give you optimisation without understanding what's going on in if condition however if result of that loop is list - you can use list comprehension:

# ensure query.order_by is iterable
query.order_by = query.orderby if geattr(query, 'orderby', None) else []
result = [ item for item in query.order_by if 'severity' in item]

Another good choice is to filter items prior iterating over them:

query.order_by = query.orderby if geattr(query, 'orderby', None) else []
for item in filter(lambda x: 'severity' in x, items):
    print item['severity']
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82
1

Something like this:

filtered = [q for q in query.orderby if 'severity' in q]

would filter into a new list

Zitrax
  • 19,036
  • 20
  • 88
  • 110
1

If query.orderby is a list of dict than you should go like that:

x = [{"severity": "asc"}, {"name": "desc"}]

for e in x:
    for key, value in e.iteritems():
        if 'severity' in key:
            print 'yes'
Rajiv Sharma
  • 6,746
  • 1
  • 52
  • 54
0

Your initial statement

if query.orderby:

in light of your answer to a comment of mine

orderby need not be present always

is not what you want... look at this interactive session

In [1]: class Query(): pass

In [2]: query = Query()

In [3]: query.orderfrom = 1

In [4]: if query.orderfrom: print(1)
1

In [5]: if query.orderby: print(1)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-27f5f9b9569b> in <module>()
----> 1 if query.orderby: print(1)

AttributeError: 'Query' object has no attribute 'orderby'

In [6]: 

My recommends are either a try ... except clause

try:
    orderby = query.orderby
except AttributeError:
    orderby = []

for q in orderby:
    if 'severity' in q:
        ...

or a solution based on getattr(), as proposed by Andriy Ivaneyko, but simpler

 # use getattr to have the attribute OR a convenient, here [], default.
 orderby = getattr(query, 'orderby', [])

 for q in orderby:
     if 'severity' in q:
         ...
Community
  • 1
  • 1
gboffi
  • 22,939
  • 8
  • 54
  • 85