5
\$\begingroup\$

Consider the following segment of code:

# Fetch my orders
orders = repo.get_orders_for(self._customer[0])

if len(orders) > 0:
    current_order_no = -1
    for (order_number, quantity, pid) in orders:

        # Print new heading if needed
        if order_number is not current_order_no:
            print("Order #{}".format(order_number))
            current_order_no = order_number

        print("    Product #{}, ordered x{}".format(pid, quantity))

I feel like there's just a lot going on. I basically do a JOIN on two tables, and return some orders and their order_items. The JOIN obviously duplicates the order_number on several rows, so I need a way of telling them apart. Is there a better way of doing this in Python (actually, I'll accept any language answer for curiosity!) Or is it my way of joining that's evil?

For the curious, the SQL statement is:

SELECT OrderNumber, Quantity, Product_ProductId FROM `order` JOIN `orderitem` ON `order`.OrderNumber = Order_OrderNumber WHERE CustomerAccount_CustomerId=%s ORDER BY OrderNumber
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$
  • You can use itertools.groupby to group the items by order number.
  • Don't use is to compare numbers. is checks object identity and the same number can be represented by different objects:

    >>> a=1234
    >>> b=1234
    >>> a is b
    False
    >>> a=12
    >>> b=12
    >>> a is b
    True                
    
  • Checking if len(orders) > 0 before the for loop is redundant. If the list is empty the loop won't run even once.

Revised code:

from itertools import groupby
from operator import itemgetter

# Fetch my orders
orders = repo.get_orders_for(self._customer[0])

for order_number, items in groupby(orders, key=itemgetter(0)):
    print("Order #{}".format(order_number))
    for _, quantity, pid in items:
        print("    Product #{}, ordered x{}".format(pid, quantity))     
\$\endgroup\$
1
  • \$\begingroup\$ Wonderful! Thanks for teaching me something new. :) \$\endgroup\$ Commented Mar 13, 2015 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.