使用if-else进行列表理解的行为

时间:2017-12-13 13:35:40

标签: python list-comprehension

我已经完成了这个列表理解,阅读了一堆" pkl"文件:

       ////  InsideView.h (My UIView which is inside my ViewController)

        @protocol InsideViewDelegate <NSObject>
        -(void)enablePan;
        -(void)disablePan;
        @end

        @interface InsideView : UIView  <UIGestureRecognizerDelegate>
        @property (nonatomic,weak)id<InsideViewDelegate>delegate;
        @end

        ////  InsideView.m   (My UIView which is inside my ViewController)

        #import "InsideView.h"
        #import <UIKit/UIKit.h>
        #import "ZCSHoldProgress.h"

        @interface InsideView(){
            BOOL panIsEnabled;
            BOOL TapAndHoldIsEnabled;
        }
        @property (nonatomic) int rectIndex;

        @property (strong, nonatomic) ZCSHoldProgress * tapAndHoldToRemovePoint;
        @property (strong, nonatomic) NSValue * discoveryCGPointValue;
        @property (nonatomic) CGPoint discoveryCGPoint;
        @end

        @implementation InsideView

        - (id)initWithFrame:(CGRect)frame{
            self = [super initWithFrame:frame];
            if (self) {

                _rectIndex=-1;

                //Boolians
                panIsEnabled=NO;
                TapAndHoldIsEnabled=NO;
                [self.delegate disableDoneButton];

            }
            return self;
        }


        -(void) setupTapAndHoldGesture{
            self.tapAndHoldToRemovePoint = [[ZCSHoldProgress alloc] initWithTarget:self action:@selector(HandleTapAndHold:)];
            self.tapAndHoldToRemovePoint.minimumPressDuration = 2.0;
            self.tapAndHoldToRemovePoint.allowableMovement =0.0;
            self.tapAndHoldToRemovePoint.delaysTouchesBegan=NO;
        //    self.tapAndHoldToRemovePoint.delaysTouchesEnded=NO;
            [self.tapAndHoldToRemovePoint setEnabled:YES];
        }
        -(void)enableTapAndHoldToRemove{
            TapAndHoldIsEnabled=YES;
            [self addGestureRecognizer:self.tapAndHoldToRemovePoint];
            for (UIGestureRecognizer * g in self.gestureRecognizers) {
                if ([g isMemberOfClass:[self.tapAndHoldToRemovePoint class]])
                    g.enabled=YES;
            }
        }
        -(void)disableTapAndHoldToRemove{
            TapAndHoldIsEnabled=NO;
            [self removeGestureRecognizer:self.tapAndHoldToRemovePoint];
            for (UIGestureRecognizer * g in self.gestureRecognizers) {
                if ([g isMemberOfClass:[self.tapAndHoldToRemovePoint class]])
                    g.enabled=NO;
            }
        }

        - (void) HandleTapAndHold:(ZCSHoldProgress *)gestureRecognizer {

            if(_rectIndex!=-1 && TapAndHoldIsEnabled){
                NSLog(@"--> isTapAndHoldEnabled =YES");

                if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
                    NSLog(@"HandleTapToRemove -->  Began");
                } else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {
                    NSLog(@" --> Changed");
                    [self.tapAndHoldToRemovePoint tearDown];
                } else if (gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
                    NSLog(@" --> Cancelled");
                    [self.tapAndHoldToRemovePoint tearDown];
                }else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
                    NSLog(@" --> Ended so removeRect”);
                    [self removePoint];
                    [self.tapAndHoldToRemovePoint tearDown];

                    panIsEnabled=YES;
                    [self.delegate enablePan];
                }else {
                    return;
                }
            }else{
                NSLog(@"--> isTapAndHoldEnabled=NO”);
                return;
            }
        }

        -(void)removeRect{
            int rectToBeRemove =[self _rectIndex];
            [self.finalPointsArray removeObjectAtIndex:rectToBeRemove];
            [self setNeedsDisplay];
        }

        - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
             CGPoint touchedPoint = [[touches anyObject] locationInView:self];

                    CGRect discoveryRect = CGRectZero;
                    for (int j=0; j<self.finalRectsArray.count;j++){
                        self.discoveryCGPointValue = [finalRectsArray objectAtIndex:j];
                        self.discoveryCGPoint =self.discoveryCGPointValue.CGPointValue;
                        discoveryRect = CGRectMake(self.discoveryCGPoint.x-15, self.discoveryCGPoint.y-15, 30, 30);

                        if(CGRectContainsPoint(discoveryRect,touchedPoint) ) {
                            ////// Rect is touched —> Activate Long Gesture & Disable Pan //////////
                            _rectIndex=j;
                            break;
                        }else{
                            ////// Didn’t touch Rect —> Disable Long Gesture & Enable Pan ////////
                            _rectIndex=-1;
                        }
                    }

                    if (_rectIndex!=-1){
                         //////Enabling LongPress Gesture & Disabling Pan //////////

                        [self setupTapAndHoldGesture];
                        [self enableTapAndHoldToRemove];

                        [self.delegate disablePan];
                        panIsEnabled =NO;

                    }else{
                        [self disableTapAndHoldToRemove];

                        [self.delegate enablePan];
                        panIsEnabled=YES;
                    }
           }
        }

        - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
            CGPoint touchedPoint = [[touches anyObject] locationInView:self];
                    [self disableTapAndHoldToRemove];
        }

        - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

                if (!panIsEnabled){
                    panIsEnabled=YES;
                    [self.delegate enablePan];
                }
                // If I enable the TapAndHoldIsEnabled here, on first touch on the blue rect, LongPressGesture’s touches began gets called without knowing what blue rect has been touched even though it only gets activated when a blue rect is touched.

                //        if (!isTapAndHoldEnabled){
                //            [self setupTapAndHoldGesture];
                //            [self enableTapAndHoldToRemove];
                //        }
                [self setNeedsDisplay];
                return;
            }
        }

        @end
////////////////////////////////////////////////////////////////////
///ImmediatePanGestureRecognizer.m  (This is my pan Gesture Subclass)

#import "ImmediatePanGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>

@implementation ImmediatePanGestureRecognizer
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        if (self.state >= UIGestureRecognizerStateBegan) {
            return;
        }
        self.state = UIGestureRecognizerStateBegan;
        [super touchesBegan:touches withEvent:event];
}
    ///////////////////////////////////////////////////////////////////

        //  ZCSHoldProgress.m   (This is my Long Press Gesture Subclass)

        #import "ZCSHoldProgress.h"
        #import <UIKit/UIGestureRecognizerSubclass.h>

        @interface ZCSHoldProgress ()

        - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
              _canRemovePoint=NO;
              UITouch *touch = (UITouch *)[touches anyObject];
              UIView *view = nil;
              for (UIGestureRecognizer *recognizer in touch.gestureRecognizers) {
                    if ([recognizer isEqual:self]) 
                       view = recognizer.view;
                       break;
                    }
              }
              self.startingPoint = [touch locationInView:view];
              self.lastTouches = touches;
              [self setup];
         }
        - (void)setup {
            if (self.progressTimer == nil) {
                self.progressTimer =
                    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
                self.startDate = [NSDate new];
            }
        }

        - (void)handleTimer:(NSTimer *)timer {
            NSTimeInterval timerElapsed = [[NSDate new] timeIntervalSinceDate:self.startDate];
            self.should_trigger = timerElapsed >= self.minimumPressDuration;
            if (timerElapsed >= self.displayDelay && self.progressView == nil) {
                [self setupProgressView];
            }
            if (self.should_trigger && !self.is_triggered) {
                self.is_triggered = YES;

                self.state = UIGestureRecognizerStateBegan;

                [self.myTarget performSelector:self.myAction withObject:self afterDelay:0.0];
            }
            [self updateProgressLayer:(timerElapsed / self.minimumPressDuration)];
        }
        @end

     ////////////////////////////////////////////////////////////////////////
    //////MyViewController.m    (This is my View Controller Class)
    #import "ImmediatePanGestureRecognizer.h"
    #import "ZCSHoldProgress.h"
    @interface SelectionVC (){
         BOOL panIsAllowed;
    }
    @property (nonatomic,strong) InsideView * insideV;

    @property (strong, nonatomic) ImmediatePanGestureRecognizer * pan;

    @end

    @implementation MyViewController
      -(void)setupPan{
        self.pan= [[ImmediatePanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanInSelectionVC:)];
        self.pan.delaysTouchesBegan = NO;
        self.pan.delaysTouchesEnded = NO;
        self.pan.delegate = self;
    }
    -(void)enablePan{
        [self setupPan];
        [myMainView addGestureRecognizer:self.pan];
        for (UIGestureRecognizer * g in myMainView.gestureRecognizers) {
            if ([g isMemberOfClass:[ImmediatePanGestureRecognizer class]])
                g.enabled=YES;
        }
    }
    -(void)disablePan{
        self.pan.cancelsTouchesInView = NO;
        [myMainView removeGestureRecognizer:self.pan];
        for (UIGestureRecognizer * g in myMainView.gestureRecognizers) {
             if ([g isMemberOfClass:[ImmediatePanGestureRecognizer class]]){
                 g.enabled=NO;
             }
         }
    }

    ////////////////////////////////////////////////////////////////////////

这是我开始工作的唯一方法。如果我在它不起作用之后添加a = [pd.read_pickle("my_file"+str(i)+".pkl" for i in range(1, 18) if os.path.exists("my_file"+str(i)+".pkl")] 子句。如果我在循环之前放置else子句它不起作用。你能解释一下原因吗?如果我这样做:

if

这个没有工作,而不是关于list_comprehensions的许多答案,其中该结构有效。

感谢。

1 个答案:

答案 0 :(得分:0)

a = [pd.read_pickle("my_file"+str(i)+".pkl" if os.path.exists("my_file"+str(i)+".pkl") else your_alternate_value for i in range(1, 18)]

或者我喜欢将其格式化以防止这么长的行:

a = [
            pd.read_pickle("my_file"+str(i)+".pkl"
        if os.path.exists("my_file"+str(i)+".pkl")
        else your_alternate_value
    for i in range(1, 18)
]

列表理解对我来说有点难以确定如何格式化。可能还有另一种我更喜欢的方式,但它还没有找到我。

解释

列表理解转换为这样的格式

some_list = []
for ...:
    for/if ...
        ...
            ...
            some_list.append(something)

然而,你需要很多块,但只会更深入。任何块只能包含另一个块或最终附加值。现在,当您考虑列表推导没有缩进时,这是有道理的。如果您有两个if块,那么理解如何知道else属于哪一个?

我的解决方案的秘诀在于它不是另一个障碍;这是附加内容的一部分。 if / else是一个表达式,与其他语言中的三元运算符相当。这是正在发生的事情:

some_list = []
for ...
    some_list.append(something if blah else some_other_thing)

这就是if / else开头的原因。