0 মানটি না সরিয়ে তালিকা থেকে কোনও মানই সরান না


244

এটি আমার সূত্রটি দিয়ে শুরু করেছি।

আমার তালিকা

L = [0, 23, 234, 89, None, 0, 35, 9]

আমি যখন এটি চালাচ্ছি:

L = filter(None, L)

আমি এই ফলাফল পেতে

[23, 234, 89, 35, 9]

তবে এটি আমার যা প্রয়োজন তা নয়, যা সত্যই আমার প্রয়োজন তা হ'ল:

[0, 23, 234, 89, 0, 35, 9]

কারণ আমি ডেটাটির পারসেন্টাইল গণনা করছি এবং 0 অনেক পার্থক্য করে।

0 মান অপসারণ ছাড়াই কোনও তালিকা থেকে কোনওটিই কীভাবে সরিয়ে ফেলবেন?

উত্তর:


354
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

কেবল মজাদার জন্য, আপনি কীভাবে filterএটি ব্যবহার না করে lambdaএটির জন্য কীভাবে মানিয়ে নিতে পারেন তা এখানে (আমি এই কোডটির সুপারিশ করব না - এটি কেবল বৈজ্ঞানিক উদ্দেশ্যে)

>>> from operator import is_not
>>> from functools import partial
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(partial(is_not, None), L)
[0, 23, 234, 89, 0, 35, 9]

23
কম মার্জিত filterসংস্করণ: filter(lambda x: x is not None, L)- আপনি lambdaব্যবহার থেকে মুক্তি পেতে পারেন partialএবং operator.is_notআমি মনে করি, তবে তালিকা-কম এত বেশি পরিচ্ছন্ন হওয়ার কারণে এটি সম্ভবত এটির পক্ষে উপযুক্ত নয়।
মিগিলসন

3
@ মিগিলসন ওহ বাহ আমি জানি না কী is_notবিদ্যমান! আমি ভেবেছিলাম এটি কেবল ছিল is_, আমি এটি কেবল মজা করার জন্য যুক্ত করব
জামিলাক

@ জামিলাক - হ্যাঁ এটি আসলে আমাকে বিরক্ত করে যা is_notবিদ্যমান এবং not_inনেই। আমি আসলে মনে করি যে এটি not_inএকটি যাদু পদ্ধতিতে পরিণত করা উচিত __not_contains__... কিছুক্ষণ আগে জিজ্ঞাসা করা একটি প্রশ্ন এবং একটি উত্তরদাতাকে আমি একটি মন্তব্য করেছি ... এবং এখনও সমাধানের মতো মনে হয় না।
মিগিলসন

@ মিগিলসন আমি মনে করি যে একই অনুমানের অধীনে আমি সবেমাত্র ধরে নিয়েছি যে এটি বিদ্যমান নেই। আমার ধারণা আপনি কেবল ব্যবহার করতে পারেন filterfalseবা ব্যবহারের ক্ষেত্রে নির্ভর করে কিছু
জামিলাক

@ জামিলাক - হ্যাঁ আমার মূল সমস্যাটি হ'ল অজগরকে x > yবোঝায় not x <= yনা কারণ আপনি কিছু করতে পারেন __lt__এবং __le__তাই কেন x not in yবোঝানো উচিত not x in y(বিশেষত যেহেতু not inএটির নিজস্ব
বাইকোড রয়েছে

136

এফডব্লিউআইডাব্লু, পাইথন 3 এই সমস্যাটিকে সহজ করে তোলে:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> list(filter(None.__ne__, L))
[0, 23, 234, 89, 0, 35, 9]

পাইথন 2 এ, আপনি পরিবর্তে একটি তালিকা বোধগম্যতা ব্যবহার করবেন:

>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

+1 আপনি কি এর __ne__মতো partialএবং এর বিপরীতে ব্যবহারের পরামর্শ দিচ্ছেন ne?
জামিলাক

1
@ জামিলাক হ্যাঁ, এটি দ্রুত, লেখার জন্য আরও সহজ এবং আরও কিছুটা পরিষ্কার।
রেমন্ড হেটেঞ্জার

operatorমডিউল ব্যবহার বিবেচনা করুন ।
রাইটফোল্ড

12
কী __ne__?
DrMcCleod

11
@DrMcCleod অভিব্যক্তি x != yঅভ্যন্তরীণভাবে আহ্বান x.__ne__(y)যেখানে NE "সমান নয়" জন্য দাঁড়িয়েছে। সুতরাং, None.__ne__একটি আবদ্ধ পদ্ধতি যা ফেরৎ সত্য যখন কোন ব্যতীত অন্য মান নামক কোনটি । উদাহরণস্বরূপ, bm = None.__ne__সাথে কল bm(10)রিটার্ন NotImplemented যা সত্য মান, এবং bm(None)আয় মিথ্যা
রেমন্ড হেটিঙ্গার

17

তালিকা বোধগম্যতা ব্যবহার করে এটি নিম্নলিখিত হিসাবে করা যেতে পারে:

l = [i for i in my_list if i is not None]

L এর মান হ'ল:

[0, 23, 234, 89, 0, 35, 9]

এই সমাধানটি ইতিমধ্যে শীর্ষ উত্তরে পাওয়া গেছে, বা আমি কিছু অনুপস্থিত?
কাসউদ

16

পাইথন ২.7 এর জন্য (পাইথন 3 সমমানের জন্য রেমন্ডের উত্তর দেখুন):

পাইথন (এবং অন্যান্য ওও ভাষাগুলি) "তেমন কিছু নয়" এমনটি সাধারণ কিনা তা জানতে আমার কমন.পিতে (যা আমি "সাধারণ আমদানি *" দিয়ে প্রতিটি মডিউলে আমদানি করি) এই লাইনগুলি অন্তর্ভুক্ত করে:

def exists(it):
    return (it is not None)

তারপরে কোনও তালিকা থেকে কোনও উপাদান অপসারণ করতে, কেবল করুন:

filter(exists, L)

আমি এটি পড়তে সহজ মনে করি, সম্পর্কিত তালিকা বোঝার চেয়ে (যা রেমন্ড তার পাইথন 2 সংস্করণ হিসাবে দেখায়)।


আমি পাইথন 3 এর জন্য রেমন্ডস সলিউশনটিকে প্রাধান্য দেব এবং তারপরে পাইথন 2 এর জন্য তালিকাটি বোঝার জন্য I তবে যদি আমাকে এই পথে যেতে হয় তবে আমি partial(is_not, None)এই সমাধানটি না করেই চাই । আমি বিশ্বাস করি এটি ধীর হবে (যদিও এটি খুব গুরুত্বপূর্ণ নয়)। তবে পাইথন মডিউলগুলি আমদানি করে বেশ কয়েকটি ক্ষেত্রে এ ক্ষেত্রে কাস্টম সংজ্ঞায়িত ফাংশনটির প্রয়োজন নেই
জামিলাক

12

@ জামিলাকের উত্তরটি বেশ সুন্দর, তবে আপনি যদি এই সাধারণ কাজটি করার জন্য কয়েকটি মডিউল আমদানি করতে না চান তবে নিজের lambdaজায়গায় লিখুন:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(lambda v: v is not None, L)
[0, 23, 234, 89, 0, 35, 9]

আপনি অবশ্যই আমার সমাধানটি সঠিকভাবে পড়েন নি যা [x for x in L if x is not None]অন্য কোডটি হ'ল একটি সংযোজন ছিল যা আমি স্পষ্ট করে
বলেছিলাম

1
@ জামিলাক - আমি এটি পড়েছি কিন্তু আপনি এই সমাধানটি অন্তর্ভুক্ত করেননি। - 4-5 বছর আগে আপনি কেন লোকের উত্তর সম্পাদনা করছেন তাও নিশ্চিত নন।

5

পুনরাবৃত্তির বনাম স্পেস , ব্যবহারের একটি বিষয় হতে পারে। বিভিন্ন পরিস্থিতিতে প্রোফাইলিং হয় "দ্রুত" এবং / অথবা "কম স্মৃতি" নিবিড় হতে পারে।

# first
>>> L = [0, 23, 234, 89, None, 0, 35, 9, ...]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9, ...]

# second
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> for i in range(L.count(None)): L.remove(None)
[0, 23, 234, 89, 0, 35, 9, ...]

দ্য প্রথম পদ্ধতির (যেমন এছাড়াও দ্বারা প্রস্তাবিত @jamylak , @Raymond Hettinger , এবং @Dipto ), মেমরি সদৃশ তালিকা যা কয়েক সঙ্গে একটি বৃহৎ তালিকার জন্য ব্যয়বহুল হতে পারে সৃষ্টি Noneএন্ট্রি।

দ্বিতীয় পদ্ধতির তালিকা মাধ্যমে একবার যায়, এবং তারপর আবার একটি না হওয়া পর্যন্ত প্রতিটি সময় Noneউপনিত। এটি কম মেমরি নিবিড় হতে পারে, এবং তালিকাটি যতই যায় ততই ছোট হবে। তালিকার আকার হ্রাসের Noneফলে সামনের প্রচুর প্রবেশের গতি বাড়তে পারে তবে প্রচুর Noneএন্ট্রি পিছনে থাকলে সবচেয়ে খারাপ পরিস্থিতি ঘটত।

সমান্তরালকরণ এবং স্থানস্থ কৌশলগুলি অন্যান্য পদ্ধতি, তবে পাইথনের প্রত্যেকটির নিজস্ব জটিলতা রয়েছে। ডেটা এবং রানটাইম ব্যবহারের ক্ষেত্রেগুলি জানা এবং সেইসাথে প্রোগ্রামটি প্রোফাইল করা যেখানে নিবিড় ক্রিয়াকলাপ বা বড় ডেটা শুরু করা যায়।

উভয় পদ্ধতির নির্বাচন করা সম্ভবত সাধারণ পরিস্থিতিতে গুরুত্বপূর্ণ হবে না। এটি স্বরলিপিটির বেশি পছন্দ হয়ে ওঠে। আসলে, এই অস্বাভাবিক পরিস্থিতিতে, numpyবা cythonপাইথন অপ্টিমাইজেশানকে মাইক্রোম্যানেজ করার চেষ্টা করার পরিবর্তে উপযুক্ত বিকল্প হতে পারে।


একেবারেই কোনও অনুরাগী নন, আপনি এই সমাধানটির সাথে দাবির পুরো সুবিধাটি হ'ল তালিকাটি এত বিশাল যে মেমরিতে নকল তালিকা তৈরি করা ব্যয়বহুল হতে পারে। ঠিক আছে তবে আপনার সমাধানটি আরও ব্যয়বহুল হবে কারণ আপনি পুরো তালিকাটি স্ক্যান করছেন L.count(None)এবং তারপরে আপনি .remove(None)একাধিকবার কল করছেন যা এটির কারণ হয়ে দাঁড়ায় আপনি যে O(N^2)পরিস্থিতি সমাধানের চেষ্টা করছেন সেটি এইভাবে মোকাবেলা করা উচিত নয়, ডেটা পুনর্গঠন করা উচিত পরিবর্তে কোনও ডেটাবেস বা ফাইলের মধ্যে এটি যদি সেই স্মৃতিশক্তি নিবিড় হয়।
জামিলাক

@ জামিলাক সত্য, তবে বিশ্বের সমস্ত বাস্তব পরিস্থিতি বা ডেটা এই নমনীয়তার অনুমতি দেয় না। উদাহরণস্বরূপ, অনেক স্মৃতি ছাড়াই সিস্টেমে এক-অফ বিশ্লেষণের মাধ্যমে "লিগ্যাসি" জিওপ্যাটিয়াল ডেটা পাম্প করা। তারপরে রণটাইম বিবেচনা করার জন্য প্রোগ্রামিংয়ের সময়ও রয়েছে। উন্নয়নের সময় সাশ্রয়ের কারণে লোকেরা প্রায়শই পাইথনে ফিরে আসে। এই উত্তরের সাথে, আমি এই সত্যের দিকে মনোযোগ আনছি যে স্মৃতিটি বিবেচনার জন্য উপযুক্ত হতে পারে তবে আমি শেষ পর্যন্ত বলেছি যে এটি স্বরলিপিটিতে বেশিরভাগ ক্ষেত্রে ব্যক্তিগত পছন্দ। আমি এটিও উল্লেখ করেছি যে ডেটা জানা গুরুত্বপূর্ণ। O(n^2)সম্পূর্ণ তালিকাটি কেবল তখনই None
কেভিন

আগ্রহী হবে যদি আপনার ব্যবহারিক উদাহরণ থাকে যেখানে এই উত্তরটি সবচেয়ে ভাল সমাধান, আমি মনে করি যে সব ক্ষেত্রেই আরও ভাল পদ্ধতির উপস্থিতি ঘটবে। উদাহরণস্বরূপ, numpyআরও অপ্টিমাইজড পদ্ধতিতে এই ধরণের অপারেশন পরিচালনা করতে সক্ষম হবেন
জামিলাক

@ জামিলাক ন্যায্য বলতে আমি numpyসাম্প্রতিক বছরগুলিতে ব্যবহার করে আসছি তবে এটি একটি পৃথক দক্ষতা। যদি পাইথনের পরিবর্তে Lতাত্ক্ষণিকভাবে কাজ করা হয় তবে তারপরে (স্ট্যাকওভারফ্লো.com numpy.array/a/ 25255015/3003133) সম্ভবত দুজনের চেয়ে ভাল তবে আমি মেমরি বনাম মেমরির প্রক্রিয়াজাতকরণের বাস্তবায়ন বিবরণ জানি না। এটি কমপক্ষে মাস্কের জন্য বুলিয়ানগুলির একটি নকল দৈর্ঘ্যের অ্যারে তৈরি করে। অ্যাক্সেস (সূচক) অপারেটরের অভ্যন্তরে তুলনার সিনট্যাক্স, আমার পক্ষে এটি নতুন। এই আলোচনাটিও আমার নজরে এনেছে । listL = L[L != numpy.array(None)]dtype=object
কেভিন

এই আলোচনাটি এখন খুব বিমূর্ত হয়ে উঠছে, আমি মনে করি না যে আপনি নিজের অভিজ্ঞতার বছরগুলিতে আমাকে একটি বাস্তব জীবনের উদাহরণ দিতে সক্ষম হবেন যেখানে এই উত্তরটি আমি পূর্বে উল্লিখিত হিসাবে ডেটা পুনর্গঠন করার ক্ষেত্রে সঠিক পন্থা।
জামিলাক

2
from operator import is_not
from functools import partial   

filter_null = partial(filter, partial(is_not, None))

# A test case
L = [1, None, 2, None, 3]
L = list(filter_null(L))

6
দয়া করে কেবল কোনও কোড নয়, ওপিকে কিছু বিশদ তথ্য দিন।
লরেন্ট LAPORTE

1
আমি করেছিলাম. তুমি কি ভাব?
med_abidi

ঠিক আছে, এটি ওপি প্রশ্নের উত্তর দেয় না। পরিবর্তে এই উত্তরটি বিবেচনা করুন: stackoverflow.com/a/16096769/1513933
লরেন্ট LAPORTE

হ্যাঁ তুমিই ঠিক. আংশিক ফিল্টার নিয়ে সমস্যা ছিল।
মেড_বিডি

2

যদি এটি সমস্ত তালিকার তালিকা থাকে তবে আপনি স্যার @ রেমন্ডের উত্তরটি সংশোধন করতে পারেন

L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) ) অজগর 2 জন্য তবে

no_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""

<< list_indice [0] তালিকাতে ভেরিয়েবলের জন্য পরিবর্তনশীল যদি না হয় তবে >> >>


1

তালিকাটি নীচের মত বলে Say

iterator = [None, 1, 2, 0, '', None, False, {}, (), []]

এটি কেবলমাত্র তাদের আইটেমগুলি ফিরিয়ে দেবে bool(item) is True

print filter(lambda item: item, iterator)
# [1, 2]

এটি সমান

print [item for item in iterator if item]

শুধু কিছুই ফিল্টার করতে:

print filter(lambda item: item is not None, iterator)
# [1, 2, 0, '', False, {}, (), []]

সমতুল্য:

print [item for item in iterator if item is not None]

মিথ্যাতে মূল্যায়ন করে এমন সমস্ত আইটেম পেতে

print filter(lambda item: not item, iterator)
# Will print [None, '', 0, None, False, {}, (), []]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.