মামলা 'সংবেদনশীল'


151

আমি এক্সপ্রেশন ব্যবহার করে ভালবাসি

if 'MICHAEL89' in USERNAMES:
    ...

USERNAMESএকটি তালিকা যেখানে ।


সংবেদনশীলতার সাথে আইটেমগুলি মেলাতে কোন উপায় আছে বা আমার একটি কাস্টম পদ্ধতি ব্যবহার করা দরকার? এই জন্য অতিরিক্ত কোড লেখার দরকার আছে কিনা তা কেবল ভাবছি।

উত্তর:


179
username = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
    ...

বিকল্পভাবে:

if username.upper() in map(str.upper, USERNAMES):
    ...

বা, হ্যাঁ, আপনি একটি কাস্টম পদ্ধতি তৈরি করতে পারেন।


8
if 'CaseFudge'.lower() in [x.lower() for x in list]
ফ্রেডলি

44
[...]পুরো তালিকা তৈরি করে। (name.upper() for name in USERNAMES)আপনি যদি এই অপারেশনটি প্রচুর পরিমাণে চালাচ্ছেন তবে প্রচুর মেমরি সঞ্চয় - একটি সময়ে কেবল একটি জেনারেটর এবং একটির প্রয়োজনীয় স্ট্রিং তৈরি করবে। (আরও বেশি সঞ্চয়, আপনি যদি ছোট বারের মতো ব্যবহারকারীর নামগুলির একটি তালিকা তৈরি করেন যা আপনি প্রতিবার যাচাই করার জন্য পুনরায় ব্যবহার করেন)
ভাইরাপটার

2
পারফরম্যান্সের কারণে ডিক তৈরির সময় সমস্ত কী কমিয়ে দেওয়া পছন্দ করুন।
রায়ান

1
যদি [x.lower () x তালিকার জন্য] যদি একটি তালিকা বোঝা হয়, তবে (নাম.ইউপার () USERNAMES- এ নামের জন্য) একটি দ্বৈত বোধগম্যতা? নাকি এর অন্য নাম আছে?
otocan

1
@otocan এটি একটি জেনারেটর এক্সপ্রেশন।
এনমিহেলস

21

আমি একটি মোড়ক তৈরি করব যাতে আপনি আক্রমণাত্মক হতে পারেন। নূন্যতম, উদাহরণস্বরূপ ...:

class CaseInsensitively(object):
    def __init__(self, s):
        self.__s = s.lower()
    def __hash__(self):
        return hash(self.__s)
    def __eq__(self, other):
        # ensure proper comparison between instances of this class
        try:
           other = other.__s
        except (TypeError, AttributeError):
          try:
             other = other.lower()
          except:
             pass
        return self.__s == other

এখন, if CaseInsensitively('MICHAEL89') in whatever:প্রয়োজনীয় হিসাবে আচরণ করা উচিত (ডান দিকের দিকটি তালিকা, ডিক, বা সেট কিনা)। (স্ট্রিং অন্তর্ভুক্তির জন্য অনুরূপ ফলাফল অর্জনে আরও বেশি প্রচেষ্টা প্রয়োজন হতে পারে unicode, জড়িত কিছু ক্ষেত্রে সতর্কতা এড়ানো ইত্যাদি)।


3
dict 'মাইকেল 89' -তে কেসআইনেসেটিভলি ('MICHAEL89'): ডিক চেষ্টা করার জন্য এটি কাজ করে না: সত্য}: মুদ্রণ "পাওয়া গেছে"
জাভিয়ার কম্বেল

2
জাভিয়ার: আপনার CaseInsensitively('MICHAEL89') in {CaseInsensitively('Michael89'):True}কাজ করার জন্য এটি প্রয়োজন , যা সম্ভবত "প্রয়োজনীয় হিসাবে আচরণ করুন" এর মধ্যে পড়ে না।
গ্যাবে

এটি করার জন্য কেবল 1 টি সুস্পষ্ট উপায় থাকার কারণে অনেক কিছুই। এটি প্রচুর ব্যবহৃত না হলে এটি ভারী বোধ করে। বলেছিল, এটা খুব মসৃণ।
এনমিকহেলস

2
@ নাথন, আমার কাছে মনে হয়েছে যে আক্রমণাত্মকভাবে ধারকটি পরিবর্তন করা হ'ল "ভারী বোধ হয়" অপারেশন। সম্পূর্ণ অ-আক্রমণাত্মক মোড়ক: এর থেকে আর কতটা "হালকা" পাওয়া যায় ?! বেশি না;-). @ জাভিয়ার, আরএইচএস এর মিশ্র-কেস কী / আইটেমগুলির সাথে ডিক্টস বা সেট রয়েছে তাদের নিজস্ব অ-আক্রমণাত্মক মোড়কের দরকার (সংক্ষিপ্ত etc.অংশের এবং আমার উত্তরের "আরও প্রচেষ্টা প্রয়োজন" ;-)।
অ্যালেক্স মার্টেলি

ভারী সম্পর্কে আমার সংজ্ঞায় এমন কিছু তৈরি করার জন্য কোডের বেশ কিছুটা লেখা রয়েছে যা কেবল একবার ব্যবহার করা হবে, যেখানে কম শক্তিশালী তবে আরও সংক্ষিপ্ত সংস্করণটি করবে। এটি যদি একাধিকবার ব্যবহৃত হতে থাকে তবে এটি পুরোপুরি বুদ্ধিমান।
এনমিকহেলস

12

সাধারণত (কমপক্ষে ওপরে) আপনি নিজের পছন্দ মতো আচরণ করতে আপনার অবজেক্টকে আকার দেন। name in USERNAMESসংবেদনশীল ক্ষেত্রে হয় না, তাই USERNAMESপরিবর্তন করা প্রয়োজন:

class NameList(object):
    def __init__(self, names):
        self.names = names

    def __contains__(self, name): # implements `in`
        return name.lower() in (n.lower() for n in self.names)

    def add(self, name):
        self.names.append(name)

# now this works
usernames = NameList(USERNAMES)
print someone in usernames

এই সম্পর্কে দুর্দান্ত বিষয়টি হ'ল এটি ক্লাসের বাইরে কোনও কোড পরিবর্তন না করেই অনেক উন্নতির পথ উন্মুক্ত করে। উদাহরণস্বরূপ, আপনি self.namesদ্রুত অনুসন্ধানের জন্য সেটটিতে পরিবর্তন করতে পারেন, বা (n.lower() for n in self.names)কেবল একবার গণনা করতে পারেন এবং এটি ক্লাসে সঞ্চয় করতে পারেন এবং আরও অনেক কিছু ...


10

str.casefoldকেস-সংবেদনশীল স্ট্রিং মিলের জন্য প্রস্তাবিত। @ এনমিকহেলস এর সমাধান তুচ্ছভাবে অভিযোজিত হতে পারে।

হয় ব্যবহার করুন:

if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):

বা:

if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):

অনুযায়ী ডক্স :

কেসফোল্ডিং হ্রাস করা সমান তবে আরও আক্রমণাত্মক কারণ এটি স্ট্রিংয়ের ক্ষেত্রে সমস্ত ক্ষেত্রে পার্থক্যগুলি সরিয়ে ফেলার উদ্দেশ্যে is উদাহরণস্বরূপ, জার্মান ছোট হাতের অক্ষর 'ß' "ss" এর সমতুল্য। যেহেতু এটি ইতিমধ্যে ছোট হাতের অক্ষর, lower()তাই 'ß' এর জন্য কিছুই করবে না; casefold() এটিকে "এসএস" এ রূপান্তর করে।


8

এখানে একটি উপায়:

if string1.lower() in string2.lower(): 
    ...

এটি কাজ করার জন্য, উভয় string1এবং string2অবজেক্ট অবশ্যই টাইপের হতে হবে string


5
অ্যাট্রিবিউটআরার: 'তালিকা' অবজেক্টের কোনও 'নিম্ন' নেই
জেফ

@ জেফ এটি কারণ আপনার উপাদানগুলির মধ্যে একটি হল একটি তালিকা, এবং উভয় বস্তুর একটি স্ট্রিং হওয়া উচিত। কোন বস্তু একটি তালিকা?
ব্যবহারকারীর

1
আমি আপনাকে ভোট দিতে চাই, তবে আপনি যদি নিজের উত্তরটি সম্পাদনা না করেন তবে আমি পারব না। তুমি একদম সঠিক.
জেফ

@ জেফ আমি স্পষ্টতা যোগ করেছি।
ব্যবহারকারী

6

আমার মনে হয় আপনাকে কিছু অতিরিক্ত কোড লিখতে হবে। উদাহরণ স্বরূপ:

if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
   ...

এক্ষেত্রে আমরা USERNAMESআপার ক্ষেত্রে রুপান্তরিত সমস্ত এন্ট্রি সহ একটি নতুন তালিকা গঠন করছি এবং তারপরে এই নতুন তালিকার সাথে তুলনা করছি।

হালনাগাদ

যেমন @ ভাইরাপ্টর বলেছেন, এর পরিবর্তে জেনারেটর ব্যবহার করা আরও ভাল map। দেখুন @Nathon এর উত্তর


অথবা আপনি itertoolsফাংশন ব্যবহার করতে পারে imap। এটি জেনারেটরের তুলনায় অনেক দ্রুত তবে একই লক্ষ্যটি সম্পাদন করে।
Wheaties

5

আপনি করতে পারেন

matcher = re.compile('MICHAEL89', re.IGNORECASE)
filter(matcher.match, USERNAMES) 

আপডেট: কিছুটা সময় খেলেছি এবং ভাবছি আপনি ব্যবহার করে আরও ভাল শর্ট সার্কিট টাইপ পদ্ধতির পেতে পারেন

matcher = re.compile('MICHAEL89', re.IGNORECASE)
if any( ifilter( matcher.match, USERNAMES ) ):
    #your code here

ifilterফাংশন, পাইথন মধ্যে আমার প্রিয় মডিউল এক itertools থেকে। এটি একটি জেনারেটরের চেয়ে দ্রুত তবে কেবল যখন ডাকা হয় তখন তালিকার পরবর্তী আইটেম তৈরি করে।


কেবল যোগ করার জন্য, প্যাটার্নটি এড়ানোর দরকার হতে পারে, কারণ এটিতে "।", "?" এর মতো অক্ষর থাকতে পারে যা নিয়মিত প্রকাশের প্যাটার্নগুলিতে স্পেসিলের অর্থ রয়েছে। এটি করতে পুনঃসেসকেপ (কাঁচা_ স্ট্রিং) ব্যবহার করুন
ইচিং চ্যাং

0

আমার 5 (ভুল) সেন্ট

'এ' "" "তে যোগ দিন (['এ'])। নিম্ন ()

হালনাগাদ

খুব, @jppi সম্পূর্ণ সম্মত, আমি খারাপ অভ্যাসের উদাহরণ হিসাবে রাখব :(


2
এটা ভুল. ওপি যা চায় তা না হলে 'a' in "".join(['AB']).lower()রিটার্নগুলি বিবেচনা করুন True
jpp

0

তালিকার পরিবর্তে অভিধানের জন্য আমার এটি দরকার ছিল, জোছনের সমাধান সেই ক্ষেত্রে সর্বাধিক মার্জিত ছিল তাই আমি এটিকে কিছুটা সংশোধন করেছি:

class CaseInsensitiveDict(dict):
    ''' requests special dicts are case insensitive when using the in operator,
     this implements a similar behaviour'''
    def __contains__(self, name): # implements `in`
        return name.casefold() in (n.casefold() for n in self.keys())

এখন আপনি তেমন একটি অভিধান রূপান্তর করতে পারেন USERNAMESDICT = CaseInsensitiveDict(USERNAMESDICT)এবং ব্যবহার করতে পারেনif 'MICHAEL89' in USERNAMESDICT:


0

এটি এক লাইনে রাখতে, আমি এটিই করেছি:

if any(([True if 'MICHAEL89' in username.upper() else False for username in USERNAMES])):
    print('username exists in list')

যদিও আমি সময় অনুযায়ী এটি পরীক্ষা করিনি। আমি জানি না এটি কতটা দ্রুত / দক্ষ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.