0
ProductMaster = { 1 : [Minor Widget,0.25,250]
                  2 : [Critical Widget,5.00,10]
                  3 : [Complete System (Basic),500,1]
                  4 : [Complete System (Deluxe),625,1]
                }

I got the dictionary (ProductMaster) above by reading a csv file and then I did some calculation to make the dictionary (productReport) below.

productReport = { 1 : [687500.0,11000,0.0]
                  2 : [250000.0,5000,12500.0]
                  3 : [1500000.0,3000,92500.0]
                  4 : [0,0,0]
                }

The first index of the list value in dictionary (productReport) above represents gross revenue, and I want to output a csv file using the dictionary above in descending order in terms of gross revenue.

with open(ProductReport_Filename, 'w') as file:

    csvWriter = csv.writer(file)

    csvWriter.writerow(["Name","GrossRevenue","TotalUnits","DiscountCost"])

    productKeys = ProductMaster.keys()

    for key,value in productReport.items():

        if key in productKeys:

            csvWriter.writerow([ProductMaster[key][0], *value])

    file.close()

The code above gives the csv file below:

Name,GrossRevenue,TotalUnits,DiscountCost
Minor Widget,687500.0,11000,0.0
Critical Widget,250000.0,5000,12500.0
Complete System (Basic),1500000.0,3000,92500.0
Complete System (Deluxe),0,0,0

But I want the csv file to be sorted by gross revenue in descending order. So, the output should be:

Name,GrossRevenue,TotalUnits,DiscountCost
Complete System (Basic),1500000.0,3000,92500.0
Minor Widget,687500.0,11000,0.0
Critical Widget,250000.0,5000,12500.0
Complete System (Deluxe),0,0,0
no1
  • 1
  • 1

5 Answers5

1

Just ignore the keys. You probably should be storing those in a list instead of a dictionary anyway; dictionaries with incrementing integer keys are not very useful.

So, ignore the keys, grab the values, and sort that list.

import csv

ProductMaster = { 1 : ['Minor Widget',0.25,250],
                  2 : ['Critical Widget',5.00,10],
                  3 : ['Complete System (Basic)',500,1],
                  4 : ['Complete System (Deluxe)',625,1]
                }

productReport = { 1 : [687500.0,11000,0.0],
                  2 : [250000.0,5000,12500.0],
                  3 : [1500000.0,3000,92500.0],
                  4 : [0,0,0]
                }

# Build up a combined list.

result = [[pm[0]]+pr for pm,pr in zip(ProductMaster.values(), productReport.values())]
result.sort( key=lambda k: -k[1] )

# Write it.

with open("x.csv", 'w') as file:
    csvWriter = csv.writer(file)
    csvWriter.writerow(["Name","GrossRevenue","TotalUnits","DiscountCost"])
    csvWriter.writerows( result )

Output:

Name,GrossRevenue,TotalUnits,DiscountCost
Complete System (Basic),1500000.0,3000,92500.0
Minor Widget,687500.0,11000,0.0
Critical Widget,250000.0,5000,12500.0
Complete System (Deluxe),0,0,0
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
1

You can create a list of tuples, then sort the data by gross revenue in descending order.

import csv

# Define the dictionaries
ProductMaster = { 1 : ['Minor Widget',0.25,250],
                  2 : ['Critical Widget',5.00,10],
                  3 : ['Complete System (Basic)',500,1],
                  4 : ['Complete System (Deluxe)',625,1]
                }

productReport = { 1 : [687500.0,11000,0.0],
                  2 : [250000.0,5000,12500.0],
                  3 : [1500000.0,3000,92500.0],
                  4 : [0,0,0]
                }

# Create a list of tuples to represent the data
data = []
for key, value in productReport.items():
    data.append((key, ProductMaster[key][0], value[0], value[1], value[2]))

# Sort the data by gross revenue
data_sorted = sorted(data, key=lambda x: x[2], reverse=True)

# Write the data to a CSV file
with open('product_sales_report.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['Product ID', 'Product Name', 'Gross Revenue', 'Total Units', 'Discount Cost'])
    for row in data_sorted:
        writer.writerow(row)
1

According to How do I sort a dictionary by value?, you may now sort dictionaries.

You can also create a new dictionary, sort and work with that, but if you want to sort the original, use the line

productReport = {k: v for k, v in sorted(productReport.items(), key=lambda item: item[1], reverse=True)}

The reverse parameter is used to return a descending order.

The complete program is below, along with an output:

import csv

ProductMaster = { 1 : ["Minor Widget",0.25,250],
                  2 : ["Critical Widget",5.00,10],
                  3 : ["Complete System (Basic)",500,1],
                  4 : ["Complete System (Deluxe)",625,1]
                }

productReport = { 1 : [687500.0,11000,0.0],
                  2 : [250000.0,5000,12500.0],
                  3 : [1500000.0,3000,92500.0],
                  4 : [0,0,0]
                }

with open("c:/users/queen/documents/testexcel.csv", 'w') as file:

    csvWriter = csv.writer(file)

    csvWriter.writerow(["Name","GrossRevenue","TotalUnits","DiscountCost"])

    productKeys = ProductMaster.keys()

    # Use 
    productReport = {k: v for k, v in sorted(productReport.items(), key=lambda item: item[1], reverse=True)}

    for key,value in productReport.items():

        if key in productKeys:

            csvWriter.writerow([ProductMaster[key][0], *value])

    file.close()

enter image description here

0

Let's try to do something without code rewriting.

One of solutions is to sort productReport dictionary by first item of key's list (in other words, according GrossRevenue)

import operator
productReport = { 1 : [687500.0,11000,0.0],
                  2 : [250000.0,5000,12500.0],
                  3 : [1500000.0,3000,92500.0],
                  4 : [0,0,0]
                }

print(dict(sorted(productReport.items(), key=operator.itemgetter(1), reverse=True)))

The dictionary will be sorted by the keys' lists. Meanwhile, lists are automatically sorted according to the first inner element. We add reverse argument to make them be sorted in descending order.

The output will look like

{ 3: [1500000.0, 3000, 92500.0], 
  1: [687500.0, 11000, 0.0], 
  2: [250000.0, 5000, 12500.0], 
  4: [0, 0, 0]
}

So, we should add one row and change the variable

    ...

    productKeys = ProductMaster.keys()
    
    sorted_productReport = dict(sorted(
                                productReport.items(), 
                                key=operator.itemgetter(1), 
                                reverse=True))

    for key,value in sorted_productReport.items():

        if key in productKeys:

            csvWriter.writerow([ProductMaster[key][0], *value])

SmiLing
  • 1
  • 2
0

The builtin sorted method can be used to sort a dictionary. https://docs.python.org/3/library/functions.html#sorted

sorted(productReport.items(), key = lambda x:x[1][0],reverse=True)

Passing an iterable dictionary items, with key being a callback function which sorts using the first list item and reverse flag for sorting with a descending order.

The output of sorted is always a list.

[(3, [1500000.0, 3000, 92500.0]), (1, [687500.0, 11000, 0.0]), (2, [250000.0, 5000, 12500.0]), (4, [0, 0, 0])]

You can easily convert it to dictionary with dict()

dict(sorted(productReport.items(), key = lambda x:x[1][0],reverse=True))
>>> {3: [1500000.0, 3000, 92500.0], 1: [687500.0, 11000, 0.0], 2: [250000.0, 5000, 12500.0], 4: [0, 0, 0]}