@@ -1148,24 +1148,31 @@ def has_value(subject, property, value):
11481148
11491149 :return: True if the value exists, False if not.
11501150 """
1151+ # Localize the method lookup to avoids repeated class-attribute resolution in the loop/logic and increase performance
1152+ compare = JsonLdProcessor .compare_values
1153+
11511154 if JsonLdProcessor .has_property (subject , property ):
11521155 val = subject [property ]
1156+
1157+ # 1. Normalize @list objects
11531158 # Avoid double checking if val is a list.
11541159 # If val is a list, then we treat is as an array (i.e. if value occurs in the list, has_value returns true)
1155- # TODO: is this desirable behavior?
11561160 if _is_list (val ):
11571161 val = val ['@list' ]
11581162
1163+ # 2. Handle Collection (Array/List)
11591164 if _is_array (val ):
1160- for v in val :
1161- # Avoid in depth comparison if the types are not the same
1162- if type ( v ) == type ( value ):
1163- return JsonLdProcessor . compare_values ( value , v )
1165+ # 'any' with a localized function is the fastest way to loop in Python
1166+ return any ( compare ( value , v ) for v in val )
1167+
1168+ # 3. Handle Single Value
11641169 # avoid matching the set of values with an array value parameter
1165- # TODO: this means that if `value` is an array, there will be no comparison at all and we default to False
1166- # is this desirable behavior?
1167- elif not _is_array (value ) and type (val ) == type (value ):
1168- return JsonLdProcessor .compare_values (value , val )
1170+ # TODO: If the parameter 'value' is an array, there will be no comparison at all if `value` is an array and
1171+ # we default to False. Hence, has_value usually returns False unless comparing against another array
1172+ # (which is rare here). Is this desirable behavior?
1173+ if not _is_array (value ):
1174+ return compare (value , val )
1175+
11691176 return False
11701177
11711178 @staticmethod
0 commit comments