You could also use dictionary comprehension if a dictionary only needs a little massaging before assigning it to tag.attrs. I know bs4 returns a list when retrieving certain attributes (like class), but I wasn't aware it returned any tuples. Lists AND tuples would probably over-complicate a one-line dictionary comprehension (to the point where it would be easier to just iterate over the dictionary to handle all the exceptions).
I'm not near a development machine, but something like the following should work if list values are the ONLY exception (assuming attr_dict is your existing dictionary of attributes):
Code:
new_tag.attrs = {k:(' '.join(v) if isinstance(v, list) else v) for (k,v) in attr_dict.items()}
You could make it a two-step process if you thought there were any tuples in the dictionary values:
Code:
intermediate_dict = {k:list(v) if isinstance(v, tuple) else v) for (k,v) in attr_dict.items()}
new_tag.attrs = {k:(' '.join(v) if isinstance(v, list) else v) for (k,v) in attr_intermediate_dict.items()}
The above would really only be useful if you were looking to retrieve a dictionary of attributes from one tag (via bs4) and transfer it to a newly created tag. Otherwise... if you have to manually specify the new attributes (or build an attr dictionary from scratch), you may as well assign them as Doitsu suggested; or just iterate over the dictionary and assign them to the new tag--handling any specific list or tuple conditions along the way.