How to Print Unicode Emojis from Dictionary's Value

Viewed 668

New to Python, been wracking my brain on this all day.

I am working with emojis' unicode values

Printing the unicode values works as expected:

print("\U0001f600")

Yields

>>> 

However, my use-case is a bit more complicated. I've imported and formatted a large set of emojis using panda and dataframes. Through a probably more-complecated-than-need-be sequence of .tolist() and zipping, I've landed on what I thought was the dictionary format that I needed.

Example .tolist() with a small dataset:

emoji_list = ['#️⃣', '*️⃣', '0️⃣', '1️⃣']

grouped_code_list = [['00000023', '0000FE0F', '000020E3'], ['0000002A', '0000FE0F', '000020E3'], ['00000030', '0000FE0F', '000020E3'], ['00000031', '0000FE0F', '000020E3']]

short_name_list = ['keycap: #', 'keycap: *', 'keycap: 0', 'keycap: 1',]

keyword_list = ['keycap', 'keycap', 'keycap', 'keycap']

I formatted the above four lists into my target dictionary:

# list into a list of lists
def extractDigits(list):
    keyword_list_list =[]
    for keyword in list:
        sub = keyword.split(', ')
        keyword_list_list.append(sub)

    return (keyword_list_list)

# implement extractDigits(list)
listed_keyword_list = extractDigits(keyword_list)

description_list = list(zip(short_name_list, listed_keyword_list))

emoji_code_list = list(zip(grouped_code_list, description_list))

emojiDictionary = dict(zip(emoji_list, emoji_code_list))

The above code gives me a dictionary comprised of the following key/value pairs:

Key: an emoji from emoji_list as a key

Value: a tuple of 1. the unicode value/s (from grouped_code_list) that represent that emoji and 2. a second tuple containing the emoji CLDR Short Name and a list of associated keywords (from description_list)

Printing that dictionary looks like this:

print(emojiDictionary)
>>> {'#️⃣': (['00000023', '0000FE0F', '000020E3'], ('keycap: #', ['keycap'])), '*️⃣': (['0000002A', '0000FE0F', '000020E3'], ('keycap: *', ['keycap'])), '0️⃣': (['00000030', '0000FE0F', '000020E3'], ('keycap: 0', ['keycap'])), '1️⃣': (['00000031', '0000FE0F', '000020E3'], ('keycap: 1', ['keycap']))}

Printing it to look a bit more nice looks like this:

for key in emojiDictionary:
    print("")
    print ("key: " + key)
    for values in emojiDictionary[key]:
        print ("value: " + str(values))


>>> key: #️⃣
>>> value: ['00000023', '0000FE0F', '000020E3']
>>> value: ('keycap: #', ['keycap'])

>>> key: *️⃣
>>> value: ['0000002A', '0000FE0F', '000020E3']
>>> value: ('keycap: *', ['keycap'])

>>> key: 0️⃣
>>> value: ['00000030', '0000FE0F', '000020E3']
>>> value: ('keycap: 0', ['keycap'])

>>> key: 1️⃣
>>> value: ['00000031', '0000FE0F', '000020E3']
>>> value: ('keycap: 1', ['keycap'])

The Problem

My goal is to be able to print the unicode values from the dictionary, joined if there are more than one, and with the added "\U" to print the emoji itself.

Here is the code to do almost all of that:

print_first_emoji = str(r'\U' + r'\U'.join(emojiDictionary["#️⃣"][0]))

yields

>>> \U00000023\U0000FE0F\U000020E3

By comparison:

print("\U00000023\U0000FE0F\U000020E3")

yields

>>> #️⃣

I've tried quite a few different things, mostly involving different ways of escaping/not escaping out the backslash.

For example, If I add in the "\U" to the source dataframe before .tolist(), the resulting list adds a "\" to escape the "\" out. So, my grouped_code_list would look like this:

grouped_code_list = [['\\U00000023', '\\U0000FE0F', '\\U000020E3'], ['\\U0000002A', '\\U0000FE0F', '\\U000020E3'], ['\\U00000030', '\\U0000FE0F', '\\U000020E3'], ['\\U00000031', '\\U0000FE0F', '\\U000020E3']]

I've considered printing with the CLDR short name, but the point in using the unicode is that I can typically print emojis' that would throw this error: "SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-19: unknown Unicode character name"

I prefer to have the option of building certain emojis with multiple unicode values when necessary, rather than throwing out hundreds of emojis because the CLDR short name isn't recognized.

Does anyone have a solution, one way or another? I am I must missing something with the way these print?

2 Answers

str(r'\U' + r'\U'.join(emojiDictionary["#️⃣"][0])) - almost there, but you don't need str (it already is a string), you need ast.literal_eval:

from ast import literal_eval
print(literal_eval(r'"\U' + r'\U'.join(emojiDictionary["#️⃣"][0])+'"'))

The main question, however, is why? You already have the emoji as the key, why not just print it? What is this whole emojiDictionary for?

It looks like the values are a list of 32-bit numbers represented in hex format. This might help you out in understanding unicode.

>>> a = ['00000023', '0000FE0F', '000020E3'] # list of values
>>> b = [int(i, 16) for i in a] # convert them to integers, base 16 since they were hex strings
>>> b
[35, 65039, 8419]
>>> c = [chr(i) for i in b] # get the characters for them
>>> c
['#', '️', '⃣']
>>> print(''.join(c)) # join those characters
#️⃣
>>> print(''.join(chr(int(i, 16)) for i in a)) #concise
#️⃣
>>>
Related