import copy


def generate_keyed_value_combinations(args):
	"""
	From this:

		args = {"attr1": ["a", "b", "c"], "attr2": ["1", "2"], "attr3": ["A"]}

	To this:

		[
			{u'attr1': u'a', u'attr2': u'1', u'attr3': u'A'},
			{u'attr1': u'b', u'attr2': u'1', u'attr3': u'A'},
			{u'attr1': u'c', u'attr2': u'1', u'attr3': u'A'},
			{u'attr1': u'a', u'attr2': u'2', u'attr3': u'A'},
			{u'attr1': u'b', u'attr2': u'2', u'attr3': u'A'},
			{u'attr1': u'c', u'attr2': u'2', u'attr3': u'A'}
		]

	"""
	# Return empty list if empty
	if not args:
		return []

	# Turn `args` into a list of lists of key-value tuples:
	# [
	# 	[(u'attr2', u'1'), (u'attr2', u'2')],
	# 	[(u'attr3', u'A')],
	# 	[(u'attr1', u'a'), (u'attr1', u'b'), (u'attr1', u'c')]
	# ]
	key_value_lists = [[(key, val) for val in args[key]] for key in args.keys()]

	# Store the first, but as objects
	# [{u'attr2': u'1'}, {u'attr2': u'2'}]
	results = key_value_lists.pop(0)
	results = [{d[0]: d[1]} for d in results]

	# Iterate the remaining
	# Take the next list to fuse with existing results
	for l in key_value_lists:
		new_results = []
		for res in results:
			for key_val in l:
				# create a new clone of object in result
				obj = copy.deepcopy(res)
				# to be used with every incoming new value
				obj[key_val[0]] = key_val[1]
				# and pushed into new_results
				new_results.append(obj)
		results = new_results

	return results